Hello! I am programming arduino UNO for controlling led strips in my room Object oriented way. Tried to make some libraries to understand how do they work, but after adding Adafruit_NeoPixel.h library and using it, my code started to behave strangely. Variables just lose their values.
I'm using PlatformIO IDE
Here's code:
main.cpp
#include <Arduino.h>
#include <Formicarium.h>
#include <ButtonInput.h>
#include <Animations.h>
#include <Adafruit_NeoPixel.h>
#define NUM_LEDS 79
const byte redPin = 3;
const byte greenPin = 5;
const byte bluePin = 6;
const byte outLedPin = 9;
const byte ventPin = 10;
const byte ledPin = 4;
const byte topButtonPin = 7;
const byte botButtonPin = 8;
const byte potPin = 19;
const byte switchPin = 2;
byte rgb[3];
// AntVent antVent(ventPin, "Ant Vent", 0);
// AntLed antLed(outLedPin, "Ant LED", 1);
// Input input(topButtonPin, botButtonPin, potPin, switchPin, 150);
Animation *animation[2];
// Adafruit_NeoPixel strip(NUM_LEDS, ledPin, NEO_GRB + NEO_KHZ800);
void setup()
{
Serial.begin(9600);
pinMode(3, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
// animation[0] = new SolidRainbow(10);
// animation[0]->firstTime(rgb);
animation[1] = new Fire(15, NUM_LEDS);
animation[1]->firstTime(rgb);
}
void loop()
{
// Serial.println(animation[0]->getDelay());
// animation[0]->execute(rgb);
// analogWrite(3, rgb[0]);
// analogWrite(5, rgb[1]);
// analogWrite(6, rgb[2]);
animation[1]->execute(rgb);
}
Animations.h
#ifndef animations
#define animations
#include "Arduino.h"
#include "Adafruit_NeoPixel.h"
class Animation
{
public:
Animation(); //class constructor
String name; //name of objecy
void setDelay(int setDelayTime); //sets delay for object
unsigned long getTime(); //returns oldTimeInt of object
int getDelay(); //returns current delayTime of object
virtual void execute(byte rgbArr[3]) = 0; //executes
virtual void firstTime(byte part[3]) = 0; //prepares for execution
virtual ~Animation(){}; //class destructor
protected:
int _delayTime;
unsigned long _oldTimeInt;
};
class SolidFade : public Animation
{ //inherited solid fade class
public:
SolidFade(int startDelayTime);
SolidFade(){};
void execute(byte rgbArr[3]); //executes solid fade function
void firstTime(byte part[3]); //prepares solid fade for execution
private:
byte _rgbPart[3]; //stores values to fade
};
class SolidRainbow : public Animation
{ //inherited solid rainbow class
public:
SolidRainbow(int startDelayTime);
SolidRainbow(){};
void execute(byte rgbArr[3]);
void firstTime(byte part[3]); //if there were an animation other than solid rainbow running before, then this should be executed to start new cycle
private:
byte _decColor; //decreasing color of rainbow cycle
byte _incColor; //increasing color of rainbow cycle
byte _rainbowCounter; //rainbow cycle counter
};
class SolidBlink : public Animation
{
public:
SolidBlink(int startDelayTime);
void execute(byte rgbArr[3]);
void firstTime(byte part[3]);
private:
byte _rgbPart[3];
bool _onOffState;//saves last state of blink
};
class Fire : public Animation
{
public:
Fire(int startDelayTime, byte numLeds);
void execute(byte rgbArr[3]);
void firstTime(byte part[3]);
private:
byte _numLeds;
Adafruit_NeoPixel _strip;
};
class Rainbow : public Animation
{
public:
Rainbow(int startDelayTime);
void execute(byte rgbArr[3]);
};
#endif
fire.cpp
#include "Arduino.h"
#include "Animations.h"
#include "Adafruit_NeoPixel.h"
Fire::Fire(int startDelayTime, byte numLeds)
{
name = "Fire";
_delayTime = startDelayTime;
byte _numLeds = numLeds;
Adafruit_NeoPixel _strip(numLeds, 4, NEO_GRB + NEO_KHZ800);
_strip.begin();
_strip.clear(); //notīra iepriekšējās krāsas no krāsu lentas
_strip.show(); //apdeito krāsu lentu, lai iepriekšējās krāsas tiktu notīrītas
_strip.fill(_strip.Color(255, 0, 0), 1, 79);
Serial.println("start");
}
void Fire::execute(byte rgbArr[3])
{
Serial.println(_numLeds);
if (millis() - _oldTimeInt >= _delayTime)
{
_oldTimeInt = millis();
byte Cooling = 55;
byte Sparking = 120;
byte heat[_numLeds];
int cooldown;
// Step 1. Cool down every cell a little
for (int i = 0; i < _numLeds; i++)
{
cooldown = random(0, ((Cooling * 10) / _numLeds) + 2);
if (cooldown > heat[i])
{
heat[i] = 0;
}
else
{
heat[i] = heat[i] - cooldown;
}
}
// Step 2. Heat from each cell drifts 'up' and diffuses a little
for (int k = _numLeds - 1; k >= 2; k--)
{
heat[k] = (heat[k - 1] + heat[k - 2] + heat[k - 2]) / 3;
}
// Step 3. Randomly ignite new 'sparks' near the bottom
if (random(255) < Sparking)
{
int y = random(7);
heat[y] = heat[y] + random(160, 255);
//heat[y] = random(160,255);
}
// Step 4. Convert heat to LED colors
for (int j = 0; j < _numLeds; j++)
{
// Scale 'heat' down from 0-255 to 0-191
byte t192 = round((heat[j] / 255.0) * 191);
// calculate ramp up from
byte heatramp = t192 & 0x3F; // 0..63
heatramp <<= 2; // scale up to 0..252
// figure out which third of the spectrum we're in:
if (t192 > 0x80)
{ // hottest
_strip.setPixelColor(j, 255, heatramp, 255);
}
else if (t192 > 0x40)
{ // middle
_strip.setPixelColor(j, heatramp, 0, 255);
}
else
{ // coolest
_strip.setPixelColor(j, 0, 0, heatramp);
}
}
_strip.show();
}
}
void Fire::firstTime(byte part[3]){
}
I want to create every led animation as object and store them in array so I could use the same function names, but in different objects, that way making my code shorter.
Fire is addressable led strip function, and it is the one that behaves strangely. When I initialize Fire object I make some variable values there, but when I try to use them in Fire::execute(), variables suddenly lose their values, both Adafruit_NeoPixel object AND other private variables.
Maybe it's just too much to handle for UNO?