abs () still printing negative numbers

Hello,

I am using an arduino leonardo and I am receiving analog data from pin A0 and then using the abs() for all of the analog data before printing it. However, when I open the serial monitor I am still seeing negative numbers being printed. Any thoughts?

You will need to post some code to show how your using the abs() function as reading an analogue pin will never give a negative value unless your using the wrong data type to read it.
IIRC there can also be problems with using abs within complex calculations and it is better to use abs on it's own line but this may have changed/improved since I read/discovered it a few years back.

The analogue input is always positive so I cannot see why you need to use abs() in the first place. I know abs() works so you are doing something silly and without seeing your code it would be silly of me to speculate.

It is not obvious to me why this thread was moved to the 'Project Guidance' forum since I see nothing to indicate that it is not a simple programming problem. Am I missing something?

Moved (back?) to Programming ...

stowite:
It is not obvious to me why this thread was moved to the 'Project Guidance' forum since I see nothing to indicate that it is not a simple programming problem. Am I missing something?

Code?
Code is my usual minimum requirement for a post in the programming section

If you have a signed integer the most significant bit is the sign bit.

abs() should clear that bit but any subsequent operations that overflow the integer can end-up writing a 1 into the sign bit.

DVDdoug:
If you have a signed integer the most significant bit is the sign bit.

abs() should clear that bit but any subsequent operations that overflow the integer can end-up writing a 1 into the sign bit.

Simply clearing the sign bit does not give you the absolute value of a negative number.

Hello,

I am working with an ardiuno leonardo. I am reading analog data out of pin A0 and abs() the numbers before printing them, but I am still seeing negative values in the serial monitor. The A0 pin is essentially reading sound waves. Additionally, our inequality equations are providing to be true when not true occasionally. Are all of the values that arduino receives throught the input being printed? Any thoughts?

#include <Keyboard.h>

int sensorPin = A0;
float average;
int average1;
int counter = 0;
int maxValue = 0;
int maxValue2 = 0;
int maxValue3 = 0;
int maxValue4 = 0;
int maxValue5 = 0;
int averageFinal = 0;
unsigned int i;
int Z0 = abs(analogRead(sensorPin) - average);
int maxArray[500];

void setup() {
  // initialize the serial communication:
  pinMode(A0, INPUT_PULLUP);
  Serial.begin(9600);
  Keyboard.begin();
}

void loop() {
  unsigned long timer = millis();
  int sum = 0;
  int count = 0;

  if (timer > 1000 && timer < 5000) {
    sum += analogRead(A0);
    count += 1;
    average = sum / count;
    Serial.println(("loading"));
  }


  //Calibration Time Zone
  if (timer > 6000 && timer < 16000) {
   
      if (timer > 6000 && timer < 8000) {
    maxArray[i] = abs(analogRead(A0) - average);

    maxArray[counter] ;
    counter = counter + 1;

    if (maxArray[i] > maxValue) {
      maxValue = maxArray[i];


    }
  }
    if (timer > 8000 && timer < 10000) {
      maxArray[i] = abs(analogRead(A0) - average);


      maxArray[counter] ;
      counter = counter + 1;

      if (maxArray[i] > maxValue2) {
        maxValue2 = maxArray[i];


      }
    }
    if (timer > 10000 && timer < 12000) {
      maxArray[i] = abs(analogRead(A0) - average);


      maxArray[counter] ;
      counter = counter + 1;

      if (maxArray[i] > maxValue3) {
        maxValue3 = maxArray[i];


      }
    }
    if (timer > 12000 && timer < 14000) {
      maxArray[i] = abs(analogRead(A0) - average);


      maxArray[counter] ;
      counter = counter + 1;

      if (maxArray[i] > maxValue4) {
        maxValue4 = maxArray[i];

      }
    }
    if (timer > 14000 && timer < 16000) {
      maxArray[i] = abs(analogRead(A0) - average);


      maxArray[counter] ;
      counter = counter + 1;

      if (maxArray[i] > maxValue5) {
        maxValue5 = maxArray[i];


      }
    }
    averageFinal = (maxValue + maxValue2 + maxValue3 + maxValue4 + maxValue5) / 5;
    Serial.print(maxArray[i]);
    Serial.print ("//");
    Serial.print(maxValue);
    Serial.print("//");
    Serial.print(maxValue2);
    Serial.print ("//");
    Serial.print ("//");
    Serial.print(maxValue3);

    Serial.print ("//");
    Serial.print(maxValue4);
    Serial.print(maxValue5);
    Serial.print("Calibrating");
    Serial.println(averageFinal);
  }
                                                                                                              
  else {
      Serial.println (abs(analogRead(sensorPin) - average));
}
  if(timer > 16000){
  if (((abs(analogRead(A0)- average))) >= 162 * 0.1) {
    Serial.println ("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
    Keyboard.press((char) 32);
  }
    else{
     
       Keyboard.releaseAll();
          Serial.println("RELEASE!!!!");                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   
  }
  }                                                                                                                                                                                                                  
                                                                                                                                                                                   
  /*
     //Testing out Max, current value calculation
    else{
    if( ((abs(analogRead(sensorPin) - average))) >= averageFinal){
     Serial.print (abs(analogRead(sensorPin) - average));
     Serial.print ("//");
     Serial.print (averageFinal);
      Serial.println ("Reached 25% MAX!!!!!!!!!!!!");
    }
    else{
      Serial.print (abs(analogRead(sensorPin) - average));
     Serial.print ("//");
     Serial.print (averageFinal);
      Serial.println ("no at max");
    }

      //Serial.println(abs(analogRead(sensorPin) - average));
      // Serial.print(",");
      //Serial.println(average1);
    }
  */
}

AWOL:
Code?
Code is my usual minimum requirement for a post in the programming section

On this basis a very high proportion of the threads in the 'Programming Problems' forum would get moved to the 'Project Guidance' forum yet most turn out to be straight forward programming problems. I don't see how just moving a thread to 'Project Guidance' makes an OP more likely to post his code.

    maxArray[counter] ;

What do you think that is doing? Might as well have

    47;

there.

Why is there all that anonymous printing? Print something before every value printed, so you know what is being printed.

  pinMode(A0, INPUT_PULLUP);

Setting the mode of the digital pin that shares space with the analog pin that you are using as an analog pin is a waste of effort.

adbc22:
Any thoughts?

I think there's quite a few things going wrong there.

int Z0 = abs(analogRead(sensorPin) - average);
Not a good idea to initialize Z0 like that when average is not yet initialized.

  if (timer > 1000 && timer < 5000) {
    sum += analogRead(A0);
    count += 1;
    average = sum / count;

How many iterations do you expect this code can do in that 4000 millisecond interval? You can overflow (int) sum there in as little as 33 iterations!

    maxArray[i] = abs(analogRead(A0) - average);

    maxArray[counter] ;
    counter = counter + 1;

I'm not even sure what you're trying to do there. What is variable "i", and is it even initialized anywhere? This looks wrong.

  if (timer > 1000 && timer < 5000) {
    sum += analogRead(A0);
    count += 1;
    average = sum / count;
    Serial.println(("loading"));
  }

That does not calculate the average.

Pete

I thought maxArray[counter]; -- actually, thats a good question, I guess I thought that is was filling the arrary. So in "Calibration Time Zone" we want to make 5 arrarys; maxValue, maxValue2, maxValue3, maxValue4, maxValue5. And then in averageFinal we are averaging them.

The crazy printing is just for testing purposes when we are looking at our data in the serial monitor.

So why exactly is setting the digital pin a waste of effort? We saw differences in our data without it.

I 100% agree with Z0, that wasn't my idea, however it is never called....

Yeah, I'm a bit confused on our five arrays that we are trying to make now...

I'm confused, I'm almost certain that calculates an average, what should be different?....

adbc22:
I'm confused, I'm almost certain that calculates an average, what should be different?....

Well there's at least two problems with the averaging code.

  1. Count and sum need to be either static or global variables. As it is they both keep getting initialized to zero each time the loop is entered.

  2. Even if you fix that it still wont work because sum will probably overflow, you'd need a long int or long unsigned at least for sum.

Don't take this the wrong way, but looking at your code I think you would be better off practicing on a few simple programming exercises first. You've got to walk before you can run.

Write a small program to find the average.
Write another to find the rectified average and RMS.
You'll learn quicker like that.

I'm almost certain that calculates an average

I am absolutely certain that it doesn't, but stuart0 has explained it.

Pete

We the average loop is only calculated once, so I don't think it's being zeroed.. also, I know how to write simple algorithm's but working with analog data has been my sruggle.

adbc22:
We the average loop is only calculated once, so I don't think it's being zeroed..

No, the main loop gets called repetitively by the code that your program runs under. You are attempting to average all of the samples that can be gathered over a 4000ms period (potentially over a million of them) and you are never getting past count 1.

Also I still haven't been able to figure out why I am getting negative values in analog data from pin A0.

But the code only takes an average for the first 1000ms to 5000m's everytime the code us flashed....

stuart0:
No, the main loop gets called repetitively by the code that your program runs under. You are attempting to average all of the samples that can be gathered over a 4000ms period (potentially over a million of them) and you are never getting past count 1.

analogRead takes about 100us - you can't have millions of samples in four seconds.