Unerwartete negative Werte von abs () funktionieren in Übereinstimmung mit analogRead

Wenn ich von A0 mit einem 0-5V-Signal auf einem Arduino-Mikro mit dem folgenden Code abtaste, erhalte ich einige negative Werte.

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

Werte:

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

Beim Ausführen der (anscheinend) mathematischen Ausführung äquivalenter Code unten Ich erhalte ausschließlich positive Werte.

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

Ich glaube nicht, dass dies ein ganzzahliger Überlauf ist, wie in diesem Beitrag , weil Wenn ich zu long sensor = 0 wechsle, erhalte ich die gleichen negativen Ergebnisse.

Was ist hier los?

Antwort

abs() ist in Arduino.h als Makro:

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

Ein Makro wird nicht auf die gleiche Weise wie eine Funktion ausgewertet.

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

Diese Anweisung wird zur Kompilierungszeit erweitert auf:

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

Jetzt Der „Fehler“ ist leicht zu verstehen. Der analoge Pin wird zweimal gelesen. Der „Fehler“ kann vermieden werden, indem Sie zuerst die folgende Zeile in Ihre Skizze einfügen:

#undef abs 

Dadurch wird das Makro abs() und die Standardbibliotheksfunktion verwendet.

Prost!

Kommentare

  • Der Fehler ist das Makro abs() in Arduino.h
  • Danke für die klare Antwort. Ich hatte keine Ahnung, dass es in der Arduino-Welt überhaupt Makros gibt. Ich habe einen -Post aus dem Jahr 2011 gefunden, in dem dies und eine kurze Liste anderer Makros besprochen wurden. Kennen Sie eine endgültige Liste? Ist es nur mehr " Arduinoesque " und eine bessere Vorgehensweise, mehrere Zuweisungen in einer Zeile zu vermeiden und sich an eine Operation pro Zeile zu halten?
  • Nein, es ist nicht arduinoesker, nur eine Operation in einer Aufgabe zu verwenden. Manchmal wird dies getan, um das Lesen zu erleichtern. Ihr Problem mit Makros hat nicht viel mit Arduino zu tun. Es geht allgemeiner darum, wie Makros vom Compiler ausgewertet werden. Der Compiler ersetzt das Makro durch das, was in der Definition von ' geschrieben ist (und fügt das Argument ein). Es ist keine Funktion. Und das ist nicht Arduino-spezifisch, sondern hängt vom Compiler ab. Sie können auch Makros verwenden, wenn Sie mit anderen Compilern programmieren. Makros können nützlich sein, aber Sie müssen sie mit Vorsicht verwenden.
  • @chrisl, es gibt bereits ein abs und labs Funktion. Das Arduino-Makro abs ist ein lächerlicher Fehler von Arduino. Aaron Ciuffo, klicken Sie auf den Link zu Arduino.h in der Antwort von Mikael Patel, dort sehen Sie die anderen Makros. Eine andere Sache ist, keine Variable mit dem Namen " B1 " zu verwenden.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.