Valorile negative neașteptate din funcția abs () funcționează în linie cu analogRead

Când eșantionăm de la A0 cu un semnal 0-5V pe un micro arduino cu codul de mai jos, am câteva valori negative.

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

Valori:

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

Când rulați (aparent) matematic cod echivalent de mai jos obțin valori exclusiv pozitive.

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

Nu cred că aceasta este o depășire a numărului întreg ca în această postare deoarece când trec la long sensor = 0 obțin aceleași rezultate negative.

Ce se întâmplă aici?

Răspuns

abs() este definit în Arduino.h ca macro:

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

O macro nu evaluează în același mod ca o funcție.

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

Această declarație va fi extinsă la compilare la:

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

Acum „eroarea” este ușor de înțeles. Pinul analogic este citit de două ori. „Eroarea” poate fi evitată adăugând următoarea linie mai întâi în schița dvs.:

#undef abs 

Aceasta va elimina macro-ul abs() și funcția de bibliotecă standard vor fi utilizate în loc.

Noroc!

Comentarii

  • Eroarea este macro-ul abs() Arduino.h
  • Vă mulțumim pentru răspunsul clar. Habar n-aveam că macro-urile există chiar în lumea Arduino. Am găsit o postare din 2011 care discuta acest lucru și o scurtă listă de alte macrocomenzi. Cunoașteți o listă definitivă? Este doar mai mult " Arduinoesque " și o practică mai bună pentru a evita mai multe atribuții într-o linie și a te lipi de o operație pe linie?
  • Nu, nu este mai arduinoesc să folosești o singură operație într-o singură sarcină. Uneori, acest lucru este făcut pentru a ușura citirea. Problema dvs. cu macrocomenzile nu are de-a face cu Arduino. Este mai general despre modul în care macro-urile sunt evaluate de compilator. Compilatorul înlocuiește macro-ul cu ceea ce este scris în definiția ' (și introduce argumentul). Nu este o funcție. Și acest lucru nu este specific Arduino, ci depinde de compilator. De asemenea, puteți utiliza macrocomenzi atunci când programați cu alte compilatoare. Macro-urile pot fi utile, dar trebuie să le folosiți cu prudență.
  • @chrisl, există deja un abs și labs funcție. Macro-ul arduino abs este o gafă ridicolă de către arduino. Aaron Ciuffo, faceți clic pe linkul către Arduino.h în răspunsul de Mikael Patel, acolo vedeți celelalte macro-uri. Un alt lucru este să nu folosiți o variabilă cu numele " B1 ".

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *