属性 嵌套库时值丢失(每次循环后)

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();
            }
        }
    }
}