arduino-millis()


10

Arduinoリファレンスからコピー-millis()

ヒント:millisのパラメーターはunsigned longであることに注意してください。プログラマーがintなどの他のデータ型を使用して計算しようとすると、エラーが生成される場合があります。

どんな数学?ミリで作業しているときに除外される他の種類の処理は何ですか?

誰かがこのステートメントを明確にしたり、例を挙げたりできますか?

回答:


8

C / C ++で方程式を記述するときはいつでも、操作されるデータ型は方程式の出力に非常に現実的な影響を与えます。

各タイプのようにintfloatunsigned long異なる動作を持っている、と記憶するには、スペースの一定量を取ります。

int (arduinoの場合)は16ビットで格納され、その値の半分は負の数に、1/2は正の値に、1つの値は0に、それぞれ-2 ^ 15(-32,768)の範囲で与えられます。 + 2 ^ 15-1(32,767)に。

unsigned long(arduino上)は32ビットですが、負として指定されているものはありません。その範囲は0〜2 ^ 32-1(4294967295)です。

どんな数学?ミリで作業しているときに除外される他の種類の処理は何ですか?

問題の核心は、millisの戻り時間が32767を超えてintに保存しようとしたときに、arduinoがそれを実行できなかったintことです。計算のタイプは、これは立入禁止です。特定の演算ではなく、より小さなデータタイプで行われる計算です。多分これらの例は役立つでしょう:

  int i = 32767;
  Serial.println(i);
  //No problems here; it fits just fine

32767

  i = 32767 + 1;
  Serial.println(i);
  //Oh no, the value didn't fit

-32768

  unsigned long fake_millis = 42000;
  i = fake_millis;
  Serial.println(i);
  //This is an example of millis going past an int

-23536

  i = -10;
  unsigned int j = i;
  Serial.println(j);
  //no way to put a negative number in an unsigned value

65526

  uint32_t k = fake_millis;
  Serial.println(k);
  //unsigned long is a uint32_t on arduino; this works great!

42000

これを実装する方法は本当に非常に天才です。これらの数値がどこから来ているのか、なぜそれらがそうなるのかについて興味がある場合は、2の補数表現の同じ説明を調べる必要があります。


単純な質問:「unsigned long fake_millis;」を宣言します。「uint_32 fake_millis;」に等しい ?
user3060854 2015年

はい、それらはarduinoで同等です。違いはunsigned long、さまざまなプラットフォーム(x86など)によって変わる可能性があり、uint32_t常にどこでも32の符号なしビットになります。
BrettAM 2015年

1
2番目の例(32767 + 1)は未定義の動作を生成することに注意してください。これはほとんど常に悪いことです。他の例は、信頼できる文書化された動作です。
Edgar Bonet、2015年

6

millis()unsigned longArduinoでは32ビットの符号なし整数であるを返します。次にunsigned int time = millis() - 1000、のようなことを行おうとすると、それを16ビットの符号なし整数に格納しようとしますunsigned int。16ビット整数は32ビット値を保持できません。

C仕様 6.3.1.3項によれば、上位16ビットは破棄されます。

可能であれば、millis()出力をa に保持し、unsigned longビットが失われないことが確実である場合にのみ、ビットの少ないデータ型を使用してください。

Cの明示的なキャストの詳細については、https//stackoverflow.com/a/13652624/1544337を参照してください。


編集ありがとうございます。uint32_tへの参照は別のものなので削除しました。uint32_tは、32ビットの符号なし整数があることを保証しますが、unsigned longは保証しません(Arduinoではそうです)。また、32ビット型であることも既に説明しました。

次に、uint32_tたまたまunsigned longオンarduino を返すと言う方が正しいと思いませんか?
BrettAM 2015年

@BrettAMに係るドキュメントこの関数は返しますunsigned long

現在のバージョンの回答では議論全体がほとんど意味をなさないため、古いコメントを削除しました。記録のためにこれを保持するだけです:変換が符号付き整数(int time = millis() - 1000)である場合、結果は同様です:上位16ビットが破棄されます。今回のC標準では、結果は実装定義であり、動作は整数の実装定義動作(4番目の箇条書き)に関するgccドキュメントで指定されています。
Edgar Bonet

2

millis()で何かをしたい場合は、変数を「uint32_t」型で初期化することを忘れないでください

「uint32_t last_millis」のようにして、「millis()」関数の出力を保存します。

それ以外の場合、他の人が言ったように、31,000を超えるとオーバーフローしますが、これはすぐに起こります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.