plus or minus notation (SOLVED)

Hi, is there a simple notation to check if a value is within a plus or minus range?

e.g. //I read a value. delay(50); //Read value again

Check IF first value is within 5 of the second value.

I can think of a few round about ways of doing this but is there any simple notation? (what I actually want to do is to check a lot more values than one and it will get very complicated with any of my solutions)

Thanks

difference = firstValue-secondValue;

if (abs(difference) > 5) { do whatever here ;}

Warning Because of the way the abs() function is implemented, avoid using other functions inside the brackets, it may lead to incorrect results. abs(a++); // avoid this - yields incorrect results

a++; // use this instead - abs(a); // keep other math outside the function

I can think of a few round about ways of doing this but is there any simple notation? (what I actually want to do is to check a lot more values than one and it will get very complicated with any of my solutions)

You should write a compare function for the whole array of variables, that keeps the code readable. and keeps the compare logic close together. e.g.

bool withinRage(int a, int b, float c, bool d ...) 
{
  ...
  return true;
};

...
if (withinRage(...)) { do this }
else { do that }

@robtillaart,

Do you have a reason to think that the abs() function will not work? I am all ears. I learn something new ever day(hour), so I am anxious to learn more.

Thanks, Jack

Your statement made 100% sense, the abs function will work 100% if you have two variables1

But the OP states (what I actually want to do is to check a lot more values than one and it will get very complicated with any of my solutions)

so I advised (maybe in too few words) to make a function that has all this “complicated check logic” in it.
That makes the code more maintainable as the complexity is localized in the new function.

One could compare the two vars without the abs() function but it would result in more code
(not much but you get the point what would happen if you have a dozen or more vars)

if (firstValue - secondValue > 5 || firstValue - secondValue < -5 ) {  do whatever here ;}

1
To name one “drawback” of the abs() method is that the positive and negative difference cannot be (easily) different.

difference = firstValue - secondValue;
if (difference > 10 || difference  < -5 ) {  do whatever here ;}

difficult to get this requirement efficient implemented with the abs() function (I did not try)

so what I proposed was a function that wraps this complexity

if ( checkAlmostEqual(firstValue, secondValue) == true ) {  do whatever here ;}  // not a serious name


bool checkAlmostEqual(int a, int b)
{
  difference = a - b;
  if (difference > 10) return true;
  if (difference < -5 ) return true;
  // optional more conditions here
  return false;
}

In practice these unbalanced conditions occur. Imagine the acceleration of a car: Speeding up the car should not be too fast (under 1G), but braking should be as fast as possible (under 6G). Also sensitivity/behaviour of sensors may not be symmetrical.

You are right, the OP first said

Check IF first value is within 5 of the second value.

And I guess I didn't read in detail the next part.

Sorry for my misunderstanding. Jack

what I actually want to do is to check a lot more values than one

Are these multiple values in one or more arrays or are they separate variables ? How they are held will make a big difference to the best solution.

Yes I am reading the same value but at different times in the loop.

Thanks for the advice folks.

Your, description is not so clear. What is the real question? Do you want to know the average of the last 4 readings, or, what?

No I am collecting values from an acclerometer sensor. I want to to determine when there is no movement and when there is no movement. I have a delay between each reading so I know what the previous reading was.

bogey: I want to to determine when there is no movement and when there is no movement.

that's a typo I assume?

Yes sorry.

It should read

I want to to determine when there is no movement and when there is movement.

But I do have a working solution by help of your comments. Thank You.

I think someone is eventually going to suggest you study the blink without delay. That will allow you to keep your micro spinning rather than taking a nap while the delay function completes.

if (timenow - timethen < 50ms)
then read the pin
and set timethen = timenow

Now do your other stuff…

Great, you have a solution. Please share that with us. And, If you feel the thread subject has been solved, please go to your first post, and modify the subject to include (SOLVED). Others may find solutions to their same kind of problem that way.

Thanks, Jack

OK so I wont post all my code because its too messy and there are other things going on but here is a snippet of how I solved this particular problem. The Sensor is an accelerometer and it is simply turning on a LED when movement has been detected.

int Sensor = 0;         
const int led = 13;
volatile int Val;

void setup(){
  pinMode(Sensor, INPUT); 
  pinMode(led, OUTPUT);  
  Val = analogRead(Sensor);
  Serial.begin(9600);                  
}

void loop(){
  int Reading1 = Val;
  int ReadingChange1 = 0;
  delay(100);

  int Reading2 = Val;
  int ReadingChange2 = Reading2 - Reading1;
  delay(100);

  int Reading3 = Val;
  int ReadingChange3 = Reading3 - Reading2;
  delay(100);
  .
  .
  .
  .
  .
  
  int Reading20 = Val;
  int ReadingChange20 = Reading20 - Reading19;
  delay(100);
  
  if ( (abs(ReadingChange1) > 2) || (abs(ReadingChange2) > 2) || (abs(ReadingChange3) > 2) || (abs(ReadingChange20) > 2)) {
    //Movement has been detected
    digitalWrite(led, HIGH);    
  }

  else {                             
    digitalWrite(led, LOW);
  }
    
}

As you can see it is not the most elegant. I did try some of the other suggestions but I could not get them to work for me. If anyone has more professional or efficient code, feel free to post but I'm fairly new to this so I'm satisfied I got it working. Thank you for your help on this.

int Reading1 = Sensor;

will not read the sensor, it will copy the pinnumber of sensor to reading1 ....

robtillaart: int Reading1 = Sensor;

will not read the sensor, it will copy the pinnumber of sensor to reading1 ....

You are dead right. I have gone back and edited my previous post. (I was trying to simplify things but forgot I had variables on another tab!)

Try this, or the ideas it uses

int sensorPin = A0;         
const int led = 13;
boolean changed;
int newReading;
int prevReading;

void setup()
{
  pinMode(led, OUTPUT);  
}

void loop()
{
  changed = false;
  prevReading = analogRead(sensorPin);
  for (int count = 1; count  < 20; count++)
  {
    newReading = analogRead(sensorPin);
    if (abs(newReading - prevReading) > 2)
    {
      changed = true;
      break;
    }
    prevReading = newReading;
    delay(100);
  }

  if (changed)
  {
    digitalWrite(led, HIGH);    
  }
  else 
  {                             
    digitalWrite(led, LOW);
  }
}

Thank You HeliBob.That looks a lot neater. I will give that a go.

A further thought. If you want to always take 20 readings before acting on a change then remove the break;