AnalogReadとインラインのabs()関数からの予期しない負の値

以下のコードを使用してarduinoマイクロで0-5V信号を使用してA0からサンプリングすると、いくつかが得られます負の値。

int sensor = 0; sensor = abs(analogRead(A0) - 512); 

値:

77 25 -74 -58 46 113 -74 102 -91 -51 -126 47 31 

(明らかに)数学的に実行する場合以下の同等のコードは、もっぱら正の値を取得します。

int sensor = 0; sensor = analogRead(A0); sensor = sensor - 512; sensor = abs(sensor); 

この投稿のように、これが整数オーバーフローではないと思います。 long sensor = 0に切り替えると、同じ否定的な結果が得られます。

ここで何が起こっているのですか?

回答

abs() Arduino.h

 #define abs(x) ((x)>0?(x):-(x)) 

マクロは関数と同じように評価されません。

 sensor = abs(analogRead(A0) - 512); 

このステートメントは、コンパイル時に次のように展開されます。

 sensor = ((analogRead(A0) - 512)>0?(analogRead(A0) - 512):-(analogRead(A0) - 512)); 

「エラー」は理解しやすいです。アナログピンは2回読み取られます。 「エラー」は、スケッチの最初に次の行を追加することで回避できます。

#undef abs 

これにより、マクロabs()標準ライブラリ関数が使用されます。

乾杯!

コメント

  • エラーはabs()マクロです。 Arduino.h
  • 明確な回答をありがとう。 Arduinoの世界にもマクロが存在することすら知らなかった。 2011年の投稿で、これと他のマクロの短いリストについて説明しているのを見つけました。あなたは決定的なリストを知っていますか? " Arduinoesque "であり、1行に複数の割り当てを避け、1行に1つの操作に固執する方がよいのでしょうか。 >
  • いいえ、1つの割り当てで1つの操作のみを使用することはArduinoesqueではありません。読みやすくするために行われることもあります。マクロに関する問題は、Arduinoとはあまり関係がありません。より一般的には、コンパイラがマクロを評価する方法についてです。コンパイラは、マクロを'の定義に記述されているものに置き換えます(そして引数を入れます)。機能ではありません。そして、これはArduino固有ではありませんが、コンパイラに依存します。他のコンパイラでプログラミングする場合は、マクロを使用することもできます。マクロは便利な場合がありますが、注意して使用する必要があります。
  • @chrisl、すでにabslabs関数。 arduino absマクロは、arduinoによるばかげた失敗です。 Aaron Ciuffo、Mikael Patelによる回答のArduino.hへのリンクをクリックすると、他のマクロが表示されます。もう1つは、" B1 "という名前の変数を使用しないことです。

コメントを残す

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