Class instantiation outside of setup() stops execution

Hi!

I am working on a little class, that controls an LED via the Adafruit_NeoPixel library, because I want to have several, independant objects of LEDs.
The compiler accepts everything, but the code seems to stop running instantly. Even the first called function in setup isn't running.

May you please give me a hint, why this takes place? I already had a look at several other classes, such as GitHub - arduino-libraries/Arduino_OAuth: OAuth 1.0 client library for Arduino where it seems to be working like this in its examples.

I can post more details if necessary, but my hope is that the problem can already be seen by the code snippets below.

Best regards!

main.ino:

#include "LED_fire.h"

Adafruit_NeoPixel stripLantern(1, LED_PIN, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel stripFires(2, LED_PIN2, NEO_GRB + NEO_KHZ800);

LED_fire LanternFire(stripLantern, 0, 100);
LED_fire LanternFire(stripFires, 0, 100);
LED_fire LanternFire(stripFires, 0, 100);

void setup() {
  [...]
  pinMode(LED_BUILTIN, OUTPUT);
  [...]
}

void loop() {
  [..]
}

LED_fire.h:

#ifndef __LED_FIRE_H__
#define __LED_FIRE_H__

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

class LED_fire {
public:
	LED_fire(Adafruit_NeoPixel &pixels, unsigned _led_num = 0, unsigned _brightness = 100);
  
	// Zyklisch aufrufen um Feuereffekt darzustellen.
	void fire(int _cooling, int _sparking, int _speedDelay);
	// Schaltet LED ab.
	void off(void);
	
private:
	unsigned led_num = 0, brightness = 100;
  
	Adafruit_NeoPixel pixels;
	// 
	void setPixel(int Pixel, byte red, byte green, byte blue);
	// 
	void setPixelHeatColor (int Pixel, byte temperature);
};

#endif // __LED_FIRE_H__

LED_fire.cpp:

#include "LED_fire.h"

LED_fire::LED_fire(Adafruit_NeoPixel &_pixels, unsigned _led_num, unsigned _brightness)
{
  pixels = _pixels;
	led_num = _led_num;
	brightness = _brightness;
	pixels.begin();
  pixels.setPixelColor(_led_num, 10, 10, 10);
	pixels.show(); // Initialize all pixels to 'off'
	pixels.setBrightness(_brightness);
}

void LED_fire::fire(int _cooling, int _sparking, int _speedDelay) {
  static byte heat;
  int cooldown;
  
  static unsigned long previousMillis;          // Variablen zur Umgehung der delay Funktion
  unsigned long currentMillis = millis();
  
  
  if (currentMillis - previousMillis >= (unsigned long)_speedDelay) {
    
    // (1) Abkuehlen der Flamme
    cooldown = random(0, _cooling);
    
    if(cooldown>heat)
      heat=0;
    else
      heat=heat-cooldown;
  }
  
  // (2) Zufaelliges neu Anfachen der Flamme
  if( (heat < 200) && (random(0,255) < _sparking) )
    heat = random(200,255);
  
  // (3) Umrechnung von Hitze zu Farbdarstellung
  setPixelHeatColor(led_num, heat);
  int flameBright = constrain(heat-100,0,255);
  pixels.setBrightness(map(flameBright, 0, 255, 0, 80));
  pixels.show();
  previousMillis = currentMillis;
}

void LED_fire::off(void) {
  setPixel(led_num, 0, 0, 0);
  pixels.show();
}

void LED_fire::setPixelHeatColor (int pixel, byte temperature) {
  byte red, green, blue;
  
  if (temperature > 0x7f) {
    red = 255;
    green = map(temperature, 0x7f, 255, 0, 255);
    blue = 0;
  }
  else {
    red = map(temperature, 0, 0x7f, 0, 255);
    green = 0;
    blue = 0;
  }
  setPixel(pixel, red, green, blue);
}

void LED_fire::setPixel(int Pixel, byte red, byte green, byte blue) {
  pixels.setPixelColor(Pixel, pixels.Color(red, green, blue));
}

LED_PIN and LED_PIN2 are not defined

tripple definition of LanternFire?

this cannot compile...

Hello

This code

pixels.begin();
pixels.setPixelColor(_led_num, 10, 10, 10);
pixels.show(); // Initialize all pixels to 'off'
pixels.setBrightness(_brightness);

Should not be in constructor, but in a begin method, that you call in setup

Thanks!

definitions were not posted, sorry. I can add them if necessarry.

Hi!

That's something I was expecting, but can you give me a hint, why that's the case? Is there something in the architecture of the arduino, that has a collision with the initialisation there? Is it the begin() function, that collides?

Hardware is not fully initialized before setup is called

Maybe look at this file to understand : ArduinoCore-avr/main.cpp at master · arduino/ArduinoCore-avr · GitHub

the compiler decides when objects gets instantiated but for global instances, their constructor will be called before main() is called, so before the Arduino gets a chance to configure all the hardware. That means that whatever you do as part of the constructor (like setting a pin as an OUTPUT) can/will be undone by the main() call later on.

having a begin() method you call from the setup gives you a chance to configure the instance after all this happened.

I still don't see how

LED_fire LanternFire(stripLantern, 0, 100);
LED_fire LanternFire(stripFires, 0, 100);
LED_fire LanternFire(stripFires, 0, 100);

would compile. it's 3 variables with the same name.... ➜ redefinition.

Hi!

Thank you very much for the information! So I'll prepare another begin() function in the class and call it in the setup routine.
Yes you are right, I modified the code slightly to provide a better overview over the problem I have and made a mistake here. It should bei sth. like:

LED_fire LanternFire(stripLantern, 0, 100);
LED_fire Fire1(stripFires, 0, 100);
LED_fire Fire2(stripFires, 1, 100);

Many thanks!

Thank you very much!
I will have a closer look at the core implementation you pointed out.

1 Like