I created an Arduino mega sketch to control LEDs channel to simulate simple sunset and sunrize. In my class LEDChannel declaration, i have an public enum to represent the state of the LED Channel and i have a private instance (CurrentState) of State enum in the class to keep track of this LEDChannel instance.
Everything compile well and is uploaded to my Arduino Mega. The problem is when i debug my code and check the value of CurrentState variable i get a value outside of enum range. Sometime i get value 7579 (actual value in my last test). Another day i can get a value of 612. The value should only be 0 to 4. I verified my code and any place i change the value of this variable, i use the enum. By example :
CurrentState = ManualSunset;
CurrentState variable receive the value NoAction in the default constructor of LEDChannel Class.
The class LEDChannel is part of a bigger project to make an Aquarium controller with other class to represent RTC time module, Bluetooth module, Fan and temperature sensor.
I developed my project with Visual Studio Community 2015 with vMicro plugin for Arduino. If you need the complete project, i will find a way to make it available.
Here is the LEDChannel Declaration/definition and main Arduino program .ino. This is a light version of my code. I removed all unnecessary code. To reproduce the problem, just comment line 13 in main program nNbLEDChannel = 1;
. You should then get value ManualSunrise (3) for variable CurrentState
. Take not that nNbLEDChannel is only used in main .ino file.
#pragma once
#if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif
//#include "DataTypes.h"
typedef byte duration;
class AquariumSimulator;
class LEDChannel
{
public:
typedef enum State
{
AutomaticSunset = 0,
AutomaticSunrise = 1,
ManualSunset = 2,
ManualSunrise = 3,
NoAction = 4
};
private:
byte MaxBrightness;
unsigned long lastTick;
byte CurrentBrightness;
LEDChannel::State CurrentState;
byte DigitalPin;
duration ManualSunsetDuration;// In secondes
duration ManualSunriseDuration;// In secondes
AquariumSimulator* pAquariumSim;
public:
void StartManualSunrise(duration SecDuration);
void PerformSunrise();
LEDChannel();
LEDChannel(byte DigitalPIN, AquariumSimulator* pSim);
private:
void PerformManualSunrise();
void SetCurrentBrightness(byte value);
void IncreaseCurrentBrightness(byte value = 1);
};
Here is the LEDChannel.cpp
#include "LEDChannel.h"
/*
Constuctor
*/
LEDChannel::LEDChannel(byte DigitalPIN, AquariumSimulator* pSim)
{
LEDChannel();
// Initialize default values
pAquariumSim = pSim;
pinMode(DigitalPIN, OUTPUT);// Configure Digital pin that control LED Channel
}
LEDChannel::LEDChannel()
{
CurrentState = NoAction;
}
void LEDChannel::PerformSunrise()
{
switch (CurrentState)
{
case AutomaticSunrise:
//PerformAutomaticSunrise();
break;
case ManualSunrise:
PerformManualSunrise();
break;
}
}
void LEDChannel::PerformManualSunrise()
{
unsigned long currentTick = millis();
if (currentTick >= (lastTick + ManualSunriseDuration / MaxBrightness))
{
// If current brightness is at max brigthness value, stop sunset
if (CurrentBrightness == MaxBrightness)
{
CurrentState = NoAction;
lastTick = 0;
}
else
{
IncreaseCurrentBrightness();
lastTick = currentTick;
}
}
}
void LEDChannel::SetCurrentBrightness(byte value)
{
if (value > 255)
CurrentBrightness = 255;
else
CurrentBrightness = value;
analogWrite(DigitalPin, CurrentBrightness);
}
void LEDChannel::IncreaseCurrentBrightness(byte value)
{
if ((CurrentBrightness + value) <= 255)
CurrentBrightness += value;
else
CurrentBrightness = 255;
SetCurrentBrightness(CurrentBrightness);
}
// Manual Sunrise for a duration in secondes
void LEDChannel::StartManualSunrise(duration SecDuration)
{
switch (CurrentState)
{
case NoAction:
CurrentState = ManualSunrise;
ManualSunriseDuration = SecDuration;
SetCurrentBrightness(0);
break;
}
}
And main program .ino
#include "LEDChannel.h"
LEDChannel** pLED;
byte nNbLEDChannel;
void setup()
{
pLED = new LEDChannel*[1];
pLED[0] = new LEDChannel(44, NULL);
/* If i put the next line as comment CurrentState get a valid value.
If i assigne a value to nNbLEDChannel I get invalid value for CurrentState*/
nNbLEDChannel = 1;
pLED[0]->StartManualSunrise(10);
}
void loop()
{
pLED[0]->PerformSunrise();
}