属性 嵌套库时值丢失(每次循环后)
Property values are lost (after each loop) when nesting libraries
我创建了 2 个库以用于我的 Arduino 代码。一个是HwSwitch库,一个是使用HwSwitch库的HwServo库。
HwSwitch 库:
HwSwitch::HwSwitch(String switchName, int switchPort, int inputType, int pressedState)
{
Name = switchName;
SwitchPort = switchPort;
_pressedState = pressedState;
_lastCheckMillis = 0;
pinMode(switchPort, inputType);
_lastPinState = digitalRead(SwitchPort);
}
bool HwSwitch::IsPressed()
{
int currentPinState = GetPinState();
return currentPinState == _pressedState;
}
bool HwSwitch::SwitchStateChanged()
{
int currentPinState = GetPinState();
if (_lastPinState != currentPinState)
{
Serial.println("---");
Serial.println("1. Now: " + String(currentPinState) + " - Prev: " + String(_lastPinState));
_lastPinState = currentPinState;
Serial.println("2. Now: " + String(currentPinState) + " - Prev: " + String(_lastPinState));
return true;
}
return false;
}
int HwSwitch::GetPinState()
{
unsigned long ms = millis();
if ((ms - _lastCheckMillis) < 50)
{
return _lastPinState;
}
_lastCheckMillis = ms;
return digitalRead(SwitchPort);
}
硬件伺服库:
HwServo::HwServo(int servoPort, int zeroPoint, HwSwitch limitSwitch)
{
_servo.attach(servoPort);
_servo.write(zeroPoint);
ServoPort = servoPort;
ZeroPoint = zeroPoint;
LimitSwitch = limitSwitch;
}
void HwServo::RotateUp()
{
_servo.write(ZeroPoint + UP);
}
void HwServo::RotateDown()
{
if (!LimitSwitch.IsPressed())
{
_servo.write(ZeroPoint + DOWN);
}
}
void HwServo::Stop()
{
_servo.write(ZeroPoint);
}
这就是我在 Arduino 代码中初始化它的方式:
HwServo HwServos[] = {
HwServo(9, 94, HwSwitch("S1", 14, INPUT_PULLUP, HIGH)),
HwServo(5, 90, HwSwitch("S2", 8, INPUT_PULLUP, HIGH)),
};
void setup() { }
void loop() {
for(int i = 0; i < 2; i++)
{
HwServo hwServo = HwServos[i];
if (hwServo.LimitSwitch.SwitchStateChanged())
{
SendSwitchStateUpdate(hwServo.LimitSwitch);
if (hwServo.LimitSwitch.IsPressed())
{
hwServo.Stop();
}
}
}
}
终于到了正题!正如您在 HwSwitch 库中所见,我使用 Serial.println 输出了一些数据。在这里我可以看到 _lastPinState 已成功更新,但在每次循环后都会重置。但是,当我直接创建一个 HwSwitch 并使用它时,_lastPinState 并没有被重置。换句话说,这个值的重置似乎只有在HwServo库内部使用HwSwitch库时才会发生。
貌似跟指针有关?我可能错误地初始化了我的 类,但我不知道如何修复它。任何人都可以帮助(最好是解释)这个问题吗?
我现在没有带 Arduino,但我看了看并重新编写了你的代码,根据我的最佳猜测添加了省略的构造函数,并让它编译。有些事情需要更正。我敢肯定还有其他方法,但我就是这样做的。
如需完整代码,请转到 here。
首先,我创建了一些指向我想要保留的对象的指针,如下所示:
HwServo *HwServos[2];
HwSwitch *s1;
HwSwitch *s2;
HwServo *sv1;
HwServo *sv2;
现在每个都保留在Arduino 的内存中。
现在,构建setup()
中的对象:
void setup() {
s1 = new HwSwitch("S1", 14, INPUT_PULLUP, HIGH);
s2 = new HwSwitch("S2", 8, INPUT_PULLUP, HIGH);
sv1 = new HwServo(9, 94, *s1);
sv2 = new HwServo(5, 90, *s2);
//Now, since you're going through an array:
HwServos[0] = sv1;
HwServos[1] = sv2;
}
使用那个设置函数!!!也许并不总是必要的,或者在某些情况下甚至是推荐的,但是收集只需要在那里创建一次的东西是很好的,尤其是在这种情况下。
请注意,new
未在任一对象的范围内使用,而是在程序的范围内使用...因此在您的对象中没有花哨的析构函数 是必要的。通常情况下,您会担心在程序终止之前(或最适合的时候)将它们全部删除,但在 Arduino 的情况下,它只会失去电源并杀死所有东西。
您应该将 class 定义更改为:
class HwSwitch {
public:
String Name;
int SwitchPort;
int _pressedState;
int _lastCheckMillis;
int _lastPinState;
HwSwitch(String, int, int, int);
bool IsPressed();
bool SwitchStateChanged();
int GetPinState();
};
class HwServo {
public:
HwServo();
HwServo(int, int, HwSwitch &);
int ServoPort;
int ZeroPoint;
HwSwitch & LimitSwitch;
void RotateUp();
void RotateDown();
void Stop();
Servo _servo;
};
注意:我制作了所有内容 public
,如果您愿意,可以随意将 private
内容移回私有。
我将构造函数更改为:
HwSwitch::HwSwitch(String switchName, int switchPort, int inputType, int pressedState)
{
Name = switchName;
SwitchPort = switchPort;
_pressedState = pressedState;
_lastCheckMillis = 0;
pinMode(switchPort, inputType);
_lastPinState = digitalRead(SwitchPort);
}
HwServo::HwServo(int servoPort, int zeroPoint, HwSwitch &limitSwitch)
{
_servo.attach(servoPort);
_servo.write(zeroPoint);
ServoPort = servoPort;
ZeroPoint = zeroPoint;
LimitSwitch = limitSwitch;
}
我这样修改了loop()
:
void loop() {
// put your main code here, to run repeatedly:
for(int i = 0; i < 2; i++)
{
if (HwServos[i]->LimitSwitch.SwitchStateChanged())
{
SendSwitchStateUpdate(HwServos[i]->LimitSwitch);
if (HwServos[i]->LimitSwitch.IsPressed())
{
HwServos[i]->Stop();
}
}
}
}
我创建了 2 个库以用于我的 Arduino 代码。一个是HwSwitch库,一个是使用HwSwitch库的HwServo库。
HwSwitch 库:
HwSwitch::HwSwitch(String switchName, int switchPort, int inputType, int pressedState)
{
Name = switchName;
SwitchPort = switchPort;
_pressedState = pressedState;
_lastCheckMillis = 0;
pinMode(switchPort, inputType);
_lastPinState = digitalRead(SwitchPort);
}
bool HwSwitch::IsPressed()
{
int currentPinState = GetPinState();
return currentPinState == _pressedState;
}
bool HwSwitch::SwitchStateChanged()
{
int currentPinState = GetPinState();
if (_lastPinState != currentPinState)
{
Serial.println("---");
Serial.println("1. Now: " + String(currentPinState) + " - Prev: " + String(_lastPinState));
_lastPinState = currentPinState;
Serial.println("2. Now: " + String(currentPinState) + " - Prev: " + String(_lastPinState));
return true;
}
return false;
}
int HwSwitch::GetPinState()
{
unsigned long ms = millis();
if ((ms - _lastCheckMillis) < 50)
{
return _lastPinState;
}
_lastCheckMillis = ms;
return digitalRead(SwitchPort);
}
硬件伺服库:
HwServo::HwServo(int servoPort, int zeroPoint, HwSwitch limitSwitch)
{
_servo.attach(servoPort);
_servo.write(zeroPoint);
ServoPort = servoPort;
ZeroPoint = zeroPoint;
LimitSwitch = limitSwitch;
}
void HwServo::RotateUp()
{
_servo.write(ZeroPoint + UP);
}
void HwServo::RotateDown()
{
if (!LimitSwitch.IsPressed())
{
_servo.write(ZeroPoint + DOWN);
}
}
void HwServo::Stop()
{
_servo.write(ZeroPoint);
}
这就是我在 Arduino 代码中初始化它的方式:
HwServo HwServos[] = {
HwServo(9, 94, HwSwitch("S1", 14, INPUT_PULLUP, HIGH)),
HwServo(5, 90, HwSwitch("S2", 8, INPUT_PULLUP, HIGH)),
};
void setup() { }
void loop() {
for(int i = 0; i < 2; i++)
{
HwServo hwServo = HwServos[i];
if (hwServo.LimitSwitch.SwitchStateChanged())
{
SendSwitchStateUpdate(hwServo.LimitSwitch);
if (hwServo.LimitSwitch.IsPressed())
{
hwServo.Stop();
}
}
}
}
终于到了正题!正如您在 HwSwitch 库中所见,我使用 Serial.println 输出了一些数据。在这里我可以看到 _lastPinState 已成功更新,但在每次循环后都会重置。但是,当我直接创建一个 HwSwitch 并使用它时,_lastPinState 并没有被重置。换句话说,这个值的重置似乎只有在HwServo库内部使用HwSwitch库时才会发生。
貌似跟指针有关?我可能错误地初始化了我的 类,但我不知道如何修复它。任何人都可以帮助(最好是解释)这个问题吗?
我现在没有带 Arduino,但我看了看并重新编写了你的代码,根据我的最佳猜测添加了省略的构造函数,并让它编译。有些事情需要更正。我敢肯定还有其他方法,但我就是这样做的。
如需完整代码,请转到 here。
首先,我创建了一些指向我想要保留的对象的指针,如下所示:
HwServo *HwServos[2];
HwSwitch *s1;
HwSwitch *s2;
HwServo *sv1;
HwServo *sv2;
现在每个都保留在Arduino 的内存中。
现在,构建setup()
中的对象:
void setup() {
s1 = new HwSwitch("S1", 14, INPUT_PULLUP, HIGH);
s2 = new HwSwitch("S2", 8, INPUT_PULLUP, HIGH);
sv1 = new HwServo(9, 94, *s1);
sv2 = new HwServo(5, 90, *s2);
//Now, since you're going through an array:
HwServos[0] = sv1;
HwServos[1] = sv2;
}
使用那个设置函数!!!也许并不总是必要的,或者在某些情况下甚至是推荐的,但是收集只需要在那里创建一次的东西是很好的,尤其是在这种情况下。
请注意,new
未在任一对象的范围内使用,而是在程序的范围内使用...因此在您的对象中没有花哨的析构函数 是必要的。通常情况下,您会担心在程序终止之前(或最适合的时候)将它们全部删除,但在 Arduino 的情况下,它只会失去电源并杀死所有东西。
您应该将 class 定义更改为:
class HwSwitch {
public:
String Name;
int SwitchPort;
int _pressedState;
int _lastCheckMillis;
int _lastPinState;
HwSwitch(String, int, int, int);
bool IsPressed();
bool SwitchStateChanged();
int GetPinState();
};
class HwServo {
public:
HwServo();
HwServo(int, int, HwSwitch &);
int ServoPort;
int ZeroPoint;
HwSwitch & LimitSwitch;
void RotateUp();
void RotateDown();
void Stop();
Servo _servo;
};
注意:我制作了所有内容 public
,如果您愿意,可以随意将 private
内容移回私有。
我将构造函数更改为:
HwSwitch::HwSwitch(String switchName, int switchPort, int inputType, int pressedState)
{
Name = switchName;
SwitchPort = switchPort;
_pressedState = pressedState;
_lastCheckMillis = 0;
pinMode(switchPort, inputType);
_lastPinState = digitalRead(SwitchPort);
}
HwServo::HwServo(int servoPort, int zeroPoint, HwSwitch &limitSwitch)
{
_servo.attach(servoPort);
_servo.write(zeroPoint);
ServoPort = servoPort;
ZeroPoint = zeroPoint;
LimitSwitch = limitSwitch;
}
我这样修改了loop()
:
void loop() {
// put your main code here, to run repeatedly:
for(int i = 0; i < 2; i++)
{
if (HwServos[i]->LimitSwitch.SwitchStateChanged())
{
SendSwitchStateUpdate(HwServos[i]->LimitSwitch);
if (HwServos[i]->LimitSwitch.IsPressed())
{
HwServos[i]->Stop();
}
}
}
}