2017-01-08 8 views
1

私はArduinoコードで使用する2つのライブラリを作成しました。 1つはHwSwitchライブラリで、もう1つは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); 
} 

そして、これは私は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はリセットされません。言い換えれば、HwSwitchライブラリがHwServoライブラリの内部で使用されている場合にのみ値をリセットすることが考えられます。

これは明らかにポインタと関係がありますか?おそらく私のクラスを間違って初期化しようとしていますが、それを修正する方法はわかりません。この問題を助けることができる人(そして説明できることが望ましい人)ですか?

+1

は 'LimitSwitch'変数に時間ファイル書き込み' HwSwitch * 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; 

今、それぞれが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(); 
      } 
     } 
    } 
} 
+0

このコードと@ frarugi87の前のコメントの説明は、コードを動作させるのに役立ちました。ありがとう! – Stitch10925

関連する問題