【发布时间】:2017-10-15 13:49:21
【问题描述】:
我创建了一个 Arduino 大型草图来控制 LED 通道以模拟简单的日落和日出。在我的类 LEDChannel 声明中,我有一个公共枚举来表示 LED 通道的状态,并且我在类中有一个 State 枚举的私有实例 (CurrentState) 来跟踪这个 LEDChannel 实例。
一切都编译好并上传到我的 Arduino Mega。问题是当我调试代码并检查 CurrentState 变量的值时,我得到的值超出了枚举范围。有时我得到值 7579(我上次测试中的实际值)。另一天,我可以得到一个 612 的值。该值应该只有 0 到 4。我验证了我的代码,并且在我更改此变量的值的任何地方,我都使用枚举。举例:
CurrentState = ManualSunset;
CurrentState 变量在 LEDChannel 类的默认构造函数中接收值 NoAction。
LEDChannel 类是一个更大的项目的一部分,它与其他类一起制作 Aquarium 控制器来表示 RTC 时间模块、蓝牙模块、风扇和温度传感器。
我使用 Visual Studio Community 2015 使用 Arduino 的 vMicro 插件开发了我的项目。如果你需要完整的项目,我会想办法让它可用。
这是 LEDChannel 声明/定义和主要 Arduino 程序 .ino。这是我的代码的精简版。我删除了所有不必要的代码。要重现该问题,只需在主程序nNbLEDChannel = 1; 中注释第 13 行即可。然后,您应该获得变量 CurrentState 的值 ManualSunrise (3)。不要认为 nNbLEDChannel 仅在主 .ino 文件中使用。
#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);
};
这里是 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;
}
}
还有主程序.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();
}
【问题讨论】:
-
请提供Minimal, Complete, and Verifiable example。
this->指针也可以省略。这是隐含的,像this->Sunrise = Sunrise;这样的声明会让人感到困惑。你在哪里初始化CurrentState? -
您好,感谢您的回答。 this-> 仅用于确保使用想要的变量来帮助我诊断问题。这是我的完整项目的链接dropbox.com/s/2k0dh1zsf49bvy5/SunsetSunriseArduino2.zip?dl=0 CurrentState 变量在 LEDChannel() 构造函数中使用 this->CurrentState = NoAction 初始化我将使用最少的代码进行更多测试并为您提供可验证的示例。
-
我刚刚更新了我的代码,以最低要求重现问题,并更新了我的描述以反映我的代码。