2017-01-08 5 views
1

내 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 라이브러리 :

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

는 그리고 이것은 내가 아두 이노 코드를 초기화하는 방법입니다 : 마지막 문제에 대한 지금

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가 재설정되지 않습니다. 즉, 값을 재설정하는 것은 HwSwitch 라이브러리가 HwServo 라이브러리 내에서 사용될 때만 발생하는 것으로 보입니다.

분명히 이것은 포인터와 관련이 있습니까? 아마도 수업을 잘못 초기화하고 있을지 모르지만 해결 방법을 모릅니다. 이 문제에 도움이 될 수있는 사람 (그리고 설명해 볼 수있는 사람)?

+1

시도가 시간의 파일 쓰기'HwSwitch * LimitSwitch에 즉 (은'LimitSwitch' 변수를 포인터를 만드는 ;). 그런 다음 생성자에 대한 포인터를 전달하면 (생성자가 '..., HwSwitch * limitSwitch'가된다)'... 94, new HwSwitch ("S1", 14 ...')로 호출한다. 마지막으로 직접 호출 (예 :'.SwitchStateChanged()')을 간접 ('-> SwitchStateChanged()')으로 변경해야합니다. 이것은 객체를 처리하는 표준 방법입니다. 그리고'HwServo' 객체를 삭제할 계획이라면, 소멸자를 만들고 그 객체도 삭제하십시오. 이것을 시도하고 문제가 해결되는지 확인하십시오. – frarugi87

+0

'new' 키워드가 사용되지 않았고 동적 메모리 할당이 발생하지 않았기 때문에 단순히 기본 소멸자를 사용하고 포인터가 범위를 벗어나게하면됩니다. – NonCreature0714

+0

@ frarugi87 (*)하지만 그 후에 메서드 나 속성에 액세스하는 방법을 찾지 못했습니다. 이제는 내가 -> 사용해야한다는 것을 알았습니다. 지금 코드를 실행했습니다. 감사합니다! – Stitch10925

답변

1

지금 내 Arduino가 없지만 코드를 다시 작성하고 생략 된 생성자를 최상의 추측에 추가하여 컴파일해야합니다. 수정이 필요한 몇 가지 사항이있었습니다. 다른 방법이있을 것이라고 확신하지만, 이것이 내가 한 것입니다.

전체 코드는 here으로 이동하십시오.

HwServo *HwServos[2]; 
HwSwitch *s1; 
HwSwitch *s2; 
HwServo *sv1; 
HwServo *sv2; 

이제 각각 아두 이노의 메모리에 예약됩니다 :

첫째, 내가 지금처럼 곁에 싶습니다 객체에 대한 몇 가지 포인터를 만들었습니다. 이제

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

이 코드와 @ frarugi87에 의한 이전 코멘트의 설명은 내가 코드를 작동시키는 것을 도왔다. 감사! – Stitch10925