2016-07-10 11 views
0

私はロボットを回避するObstacleに取り組んでいます。今のところ、これ以外はすべてが正常に動作しています。ボタンプレス(Arduino)に基づいて実行中のwhileループを中断する方法はありますか?

私は2つのモードがあります。アイドルおよび障害回避。 Idleは、基本的にLEDを点滅させ、ロボットが実行している可能性のあるアクティビティをすべて停止します。ボタンを押すとモードが切り替わります。

void manageRobotState() { 
    if (digitalRead(button) == LOW) { 
    robotState = 0; 
    halt(); 
    idlePose(); 
    blinkLED(leftLED, 1000); 
    blinkLED(rightLED, 1000); 
    } else if (digitalRead(button) == HIGH) { 
    robotState = 1; 
    digitalWrite(leftLED, HIGH); 
    digitalWrite(rightLED, HIGH); 
    simpleObstacleAvoidence(); 
    } 
    delay(100); 
} 

だからここで重要なボタンをクリックすると、robotState変数が変更されることを示します。ここではというん機能です。今度はこのコードは、を除いて、ロボットが操舵している場合を除きます。

void smartTurnLeft() { 
    turning(); 
    while (currentDistanceAhead <= minimumDistance) { 
    Serial.println("turning"); 
    if (robotState == 0) { 
     break; 
    } 
    scanAhead(); 
    leftMotor.setSpeed(50); 
    rightMotor.setSpeed(50); 
    leftMotor.run(BACKWARD); 
    rightMotor.run(BACKWARD); 
    blinkLED(leftLED, 20); 
    digitalWrite(rightLED, LOW); 
    delay(20); 
    } 
} 

このループが実行されているときに何も起こり得ないと感じていますか?私はボタンを押すが、whileループは実行を続けている。何かできることはありますか?私はArduinoのについて何も知らないが、それはちょうどC.

のようだったので、私はArduinoの中volatileキーワードについてthis参照を発見したと仮定:

完全なコードはHERE

+0

のように、smartTurnLeft()機能にwhile loop内でごmanageRobotState()関数を呼び出すことであると思いますArduinoはCではありません。 – Olaf

+0

私は@Olafを修正しました。 –

答えて

1

免責を見ることができます。これはCのように動作します。問題は、if (robotState == 0)のテストが最適化されていることです。なぜなら、コンパイラはrobotStateがループ内で更新されていないことを知ることができるからです。

volatileキーワードは、このメモリアドレスがハードウェアレジスタであるか、別の実行スレッドによって更新される可能性があるため、通常のプログラムフローの外側で更新される可能性があることをコンパイラに通知します。したがって、コードの変更は、robotStateの宣言になります。他の変数にも同様の問題があるかもしれません。

+0

正しい方向@Daveで私を指してくれてありがとう、本当にここで助けてくれてありがとう!割り込みによって呼び出される関数を通じて 'robotState'変数を変更することが成功の鍵でした!興味深いことに、 'robotState''int'を' volatile'と宣言しなくても動作します。 –

0

私はあなたがしなければならない唯一の事だけfunction.And、私は方法が表示されないだけで、この

manageRobotState(); 
if (robotState == 0) { 
    break; 
} 
関連する問題