Valores negativos inesperados da função abs () em linha com analogRead

Ao fazer a amostragem de A0 com um sinal de 0-5 V em um micro arduino com o código abaixo, obtenho alguns valores negativos.

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

Valores:

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

Ao executar o (aparentemente) matematicamente código equivalente abaixo eu obtenho valores exclusivamente positivos.

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

Não acho que seja um estouro de número inteiro como nesta postagem porque quando eu mudo para long sensor = 0, obtenho os mesmos resultados negativos.

O que está acontecendo aqui?

Resposta

abs() é definido em Arduino.h como uma macro:

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

Uma macro não avalia da mesma forma que uma função.

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

Esta instrução será expandida em tempo de compilação para:

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

Agora o “erro” é fácil de entender. O pino analógico é lido duas vezes. O “erro” pode ser evitado adicionando a seguinte linha primeiro em seu esboço:

#undef abs 

Isso removerá a macro abs() e a função de biblioteca padrão serão usados em seu lugar.

Saúde!

Comentários

  • O erro é a macro abs() em Arduino.h
  • Obrigado pela resposta clara. Eu não tinha ideia de que macros existiam no mundo do Arduino. Encontrei uma postagem de 2011 discutindo isso e uma pequena lista de outras macros. Você conhece uma lista definitiva? É apenas mais " Arduinoesco " e uma prática melhor para evitar várias atribuições em uma linha e manter uma operação por linha?
  • Não, não é mais arduíno usar apenas uma operação em uma atribuição. Às vezes, isso é feito para facilitar a leitura. Seu problema com macros não tem muito a ver com o Arduino. É mais geralmente sobre como as macros são avaliadas pelo compilador. O compilador substitui a macro pelo que está escrito na definição da ' (e coloca no argumento). Não é uma função. E isso não é específico do Arduino, mas depende do compilador. Você também pode usar macros ao programar com outros compiladores. As macros podem ser úteis, mas você deve usá-las com cuidado.
  • @chrisl, já existe um abs e labs função. A macro arduino abs é um erro crasso do arduino. Aaron Ciuffo, clique no link para Arduino.h na resposta de Mikael Patel, aí você vê as outras macros. Outra coisa é não usar uma variável com o nome " B1 ".

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *