我在我的Arduino代码中创建了2个库。一个是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 Library:
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库时才会重置值。
显然这与指针有关?我可能错误地初始化了我的类,但我不知道如何解决它。有谁可以帮助(并最好解释)这个问题?
答案 0 :(得分:1)
我现在没有把我的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 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();
}
}
}
}