Getting "hard Fault" instantly

I’ve been trying to write a new library, and now I’ve gotten no compiler errors I finally flashed my code, only to get a hard fault right of the bat.
I was hoping someone could help me diagnose the problem.
This is my main code:

#include "lights.h"
#include "neopixel/neopixel.h"
#include "application.h"




#define PIXEL_PIN D0
#define PIXEL_COUNT 60
#define PIXEL_TYPE WS2812B

int select;


//constructor
lights lightstrip = lights(PIXEL_COUNT, PIXEL_PIN, PIXEL_TYPE);





void setup() {
    Particle.subscribe("value", orders);
    
}

void loop() {
    //control();

}





void orders(const char *event, const char *data)
{
    /*
    If they are the same, strcmp will return 0.
    */

  if (strcmp(data,"rainbow")==0) {
      select=0;
  }
  
  else if (strcmp(data,"wave")==0) {
      select=1;
  }
  else if (strcmp(data,"spread")==0) {
      select=2;
  }
  else if (strcmp(data,"spectrum")==0) {
      select=3;
  }
  else if (strcmp(data,"off")==0) {
      select=4;
  }
  else if (strcmp(data,"solaire")==0) {
      select=5;
  }
    
  else {
    // if the data is something else, don't do anything.
    }
}



void control() {
    
    switch(select) {
        
        case 0: lightstrip.rainbow();
            break;
        
        case 1: lightstrip.wave();
            break;
        
        case 2: lightstrip.spread();
            break;
        
        case 3: lightstrip.spectrum();
            break;
            
        case 4: lightstrip.off();
            break;
        
        case 5: lightstrip.setColor(255,147,51);
            break;
    }
    
}

This is lights.cpp:

#include "lights.h"
#include "neopixel/neopixel.h"

#define DEFAULT_SPEED 20

int speed = DEFAULT_SPEED;

//constructor
lights::lights(uint16_t n, uint8_t p, uint8_t t) : Adafruit_NeoPixel(n,p,t) {
    begin();
    show();

};



//These are different ways to display
 
void lights::rainbow() {
    uint16_t i, j;
    
    for (j = 0; j < 256; j++) {
        for (i = 0; i < numPixels(); i++) {
            setPixelColor(i, Wheel((i + j) & 255));
        }
        show();
        delay(speed);
    }
}


void lights::wave() {
    uint16_t i, j;

    for (j = 0; j < 256; j++) {
        for (i = 0; i < (numPixels() / 2); i++) {
            setPixelColor(29 - i, Wheel((i + j) & 255));
            setPixelColor(30 + i, Wheel((i + j) & 255));
        }
        show();
        delay(speed);
    }
}


void lights::spread() {
    uint16_t i, j;

    for (j = 0; j < 256; j++) {
        for (i = 0; i < ((numPixels() / 2)+1); i++) {
            setPixelColor(60 - i, Wheel((i + j) & 255));
            setPixelColor(0 + i, Wheel((i + j) & 255));
        }
        show();
        delay(speed);
    }
}


void lights::spectrum() {
    uint16_t i, j;
    for (j = 0; j < 256; j++) {
        for (i = 0; i < numPixels(); i++) {
            setPixelColor(i, Wheel((j) & 255));
        }
        show();
        delay(speed);
    }
}

void lights::off() {
    for(uint16_t i=0; i<numPixels(); i++) {
    setPixelColor(i, 0);
    show();
    delay(speed);
  }
    
}



void lights::setColor(uint32_t r, uint32_t g, uint32_t b) {
    uint16_t i;
    for (i = 0; i < numPixels(); i++) {
        setPixelColor(i,r,g,b);
    }
    show();
    delay(speed);
    
}


void lights::setSpeed(uint32_t speedset) {
    speed=speedset;
}



//Private
uint32_t lights::Wheel(byte WheelPos) {
    if (WheelPos < 85) {
        return Color(WheelPos * 3, 255 - WheelPos * 3, 0);
    } else if (WheelPos < 170) {
        WheelPos -= 85;
        return Color(255 - WheelPos * 3, 0, WheelPos * 3);
    } else {
        WheelPos -= 170;
        return Color(0, WheelPos * 3, 255 - WheelPos * 3);
    }
}

and this is lights.h:

#ifndef lights_H
#define lights_H
#include "neopixel/neopixel.h"
#include "application.h"

class lights : Adafruit_NeoPixel {
    public:
        //constructor
        lights(uint16_t n, uint8_t p, uint8_t t);
    
        int speed;
    
        //fancy functions    
        void 
            rainbow(),
            wave(),
            spread(),
            spectrum(),
            off(),
            setColor(uint32_t r, uint32_t g, uint32_t b),
            setSpeed(uint32_t speedset);
            
    private:
        uint32_t Wheel(byte);
            

        
        

};

#endif

I really have no idea where to go about troubleshooting this, so any help would be greatly appreciated.

My guess is that you need to move the calls to begin and show out of the constructor to a new method in the lights class. It’d create a new method called setup, and you’d call lightstrip.setup() out of setup().

Because the you have a global lightstrip object, it is constructed very early, before setup is called. That’s way too early to call begin and show in the Neopixel library. You need to wait until at least setup to do it. The easiest way to do that is separate constructor stuff, which may occur at global initialization and stuff that actually should be called at setup.

1 Like

A derived class would enable you to use the neopixel class's member functions including the begin() method that is part of that library, and required but missing from OP's code.

Below is an example that works... I wrote it for a non-blocking candle simulator.

@chtapodi

You should try to get rid of all that blocking code in those methods... they are really low-budget examples and not useful if you want to do much else with your device...

The code below has an update() method you can review to see if you want to un-block your new Class.

#include "neopixel.h"

#define PIXEL_COUNT 3
#define PIXEL_PIN D2
#define PIXEL_TYPE WS2812B    // I'M USING GRB WS2821B's here

enum CandleStates{
  BURN_CANDLE,
  FLICKER_CANDLE,
  FLUTTER_CANDLE,
  MODES_MAX_CANDLE
};

enum PixelSelect{
  EVERY_PIXEL,
  SINGLE_PIXEL,
};

class Candle : public Adafruit_NeoPixel
{
  public:
    Candle(uint16_t count, uint8_t pin, uint8_t type);
    Candle(uint16_t count, uint8_t pin, uint8_t type, PixelSelect pixel, uint32_t pixNum = 0);
    ~Candle(){};
    void update();

  private:
    bool fire(uint8_t greenDropValue, uint32_t cycleTime);

    PixelSelect _pixelMode = EVERY_PIXEL;
    uint32_t _pixNum = 0;
    CandleStates _mode;
    uint32_t _lastModeChange;
    uint32_t _modeDuration;

    uint8_t _redPx = 255;
    uint8_t _bluePx = 10; //10 for 5v, 15 for 3.3v
    uint8_t _grnHigh = 100; //110-120 for 5v, 135 for 3.3v
    uint8_t _grnPx = 100;

    uint32_t _lastBurnUpdate = 0;
    int _direction = 1;
};

Candle::Candle(uint16_t count, uint8_t pin, uint8_t type) : Adafruit_NeoPixel(count, pin, type)
{
  randomSeed(Time.now() + micros());
  _mode = BURN_CANDLE;
}

Candle::Candle(uint16_t count, uint8_t pin, uint8_t type, PixelSelect pixel, uint32_t pixNum) : Adafruit_NeoPixel(count, pin, type)
{
  _pixelMode = pixel;
  _pixNum = pixNum;
}

void Candle::update()
{
  if(millis() - _lastModeChange > _modeDuration)
  {
    _mode = static_cast<CandleStates>(random(MODES_MAX_CANDLE));
    _modeDuration = random(1000, 8000);
    _lastModeChange = millis();
  }
  switch(_mode)
  {
    case BURN_CANDLE:
      this->fire(10, 120);
      break;
    case FLICKER_CANDLE:
      this->fire(15, 120);
      break;
    case FLUTTER_CANDLE:
      this->fire(30, 120);
      break;
  };
}

bool Candle::fire(uint8_t greenDropValue, uint32_t cycleTime)
{
  int currentMillis = millis();
  if(currentMillis - _lastBurnUpdate > (cycleTime / greenDropValue / 2))
  {
    _grnPx = constrain(_grnPx += _direction, _grnHigh - greenDropValue, _grnHigh);
    if(_grnPx == _grnHigh - greenDropValue or _grnPx == _grnHigh)
    {
      _direction *= -1;
    }
    switch (_pixelMode)
    {
      case EVERY_PIXEL:
        for(int i = 0; i < this->numPixels(); i++)
        {
          this->setPixelColor(i, _grnPx, _redPx, _bluePx);
        }
        break;
      case SINGLE_PIXEL:
        this->setPixelColor(_pixNum, _grnPx, _redPx, _bluePx);
        break;
    }
    this->show();
    _lastBurnUpdate = currentMillis;
  }
}


Candle candle = Candle(PIXEL_COUNT, PIXEL_PIN, PIXEL_TYPE, SINGLE_PIXEL);

void setup()
{
	candle.begin();
  	candle.show();
}

void loop()
{
	candle.update();
}

1 Like

Oh man, You just introduced me to the concept of blocking and unblocking code.

I don’t understand it, but when I have time I’m gonna try to figure out your code and base it off that. From what I looked up it seems like it would solve quite a few problems I’ve had.

Thanks

Thanks, that did solve the issue of immediate hard failure, but now I get the problem of

In function `lights::setup()':
lights.cpp:17: undefined reference to `lights::show()'

And I don’t know enough about C++ yet to fix it.

Right now I am just calling show() in the lights class in the setup method, but I think I have to reference the actual Neopixel object?

I’m not exactly sure what I’m missing

Can you post what you have?