map関数の後に制約関数が使用されるのはなぜですか?

サンプルコードを読んでいて、IRセンサーからのデータをマッピングする次の方法を使用しています:

 sensor1 = analogRead(0); adj_1 = map(sensor1, s1_min, s1_max, 0, 255); adj_1 = constrain(adj_1, 0, 255); 

adj_1がすでにividから値0〜255を取得している場合、ここでconstrainを使用する意味は何ですか。 = “ee9c7017f7″>

関数?

コメント

  • s1_mins1_max生の読み取り値の保証または予想制限? map()は出力を制約しません。
  • @EdgarBonet '出力を制約しないとはどういう意味ですか? '値0〜255を返しますか?
  • 必ずしも線形マッピングである必要はありません。
  • 申し訳ありませんが、それは何ですか。
  • 線形関数

回答

公式Arduinoサイトから

[マップ関数]は、範囲外の値が意図されて有用な場合があるため、値を範囲内に制限しません。範囲の制限が必要な場合は、constraint()関数をこの関数の前または後に使用できます。

編集:例。

次のコードを使用して、自分でこれを試すことができます。

int val = 20; val = map(val, 0, 10, 0, 100); 

値の範囲の上限を10に設定しましたが、それよりも高い値を指定すると、関数はそれに応じて線形にマッピングし、200の出力になります。

回答

1つの注意点Arduinoはこの範囲外を読み取ることができないため、0〜1023の範囲の入力をマッピングする場合は、制約する必要はありません。0から1023までの各反復を実行し、対応するマッピング値を出力することで、これを確認できます。 :

for (int i = 0; i < 1024; i++){ Serial.print(i); Serial.print(","); Serial.println(map(i, 0, 1023, 0, 255)); } 

確かに、センサーの読み取り値が0から1023未満の範囲を提供する場合は、LoganBladeのようにconstraint()関数が必ず必要です。例。それ以外の場合は必要ありませんが、それでもベストプラクティスの領域に入る可能性があります。

このロジックの唯一の問題は、10進値にマッピングする場合です(これは、関数はとにかく長い型を返します)、その場合、Arduinoの内部型キャストは最小値のマッピングを切り捨てます。例:

map(0, 0, 1023, 8.9, 61.9)); >> 0 becomes 8 map(1023, 0, 1023, 8.9, 61.9)); >> 1023 becomes 61 

繰り返しになりますが、ベストプラクティスとマッピングのバグを見つけるために無駄になる可能性があるため、constrain()を使用する方がスキップするよりも優れています。 。

コメント

  • 一部のセンサーは、通常の動作範囲外の場合、または他の何かがオフの場合に、高い数値を出力します。 STM VLS30Xは、たとえば487(mm)を測定した後、突然8190を出力する可能性があります。したがって、制約は必須です。マッピングエラーの解決策も参照してください。ユーザーが多すぎると、 jetmore.org/john/blog/2011/09/ …

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です