Comparing Values

Hi All,

Totally new to this, and have my first project. I am reading a sensor, that changes its Resistance depending on what liquid it senses. What I would like to do is read this value (I have already got this working and currently outputting the value into a serial control) then depending on the reading preform actions. I think I am going about it wrong, and I can get > and < to work, but not a range.

So.
If sensor is between 2500 - 6000 LED1 is High
If sensor is between 8000 - 12000 LED2 is High
If sensor is between 13000 - 17000 LED3 is high
If sensor is greater that 18000 LED4 is high

Guess I need to do an Else If statement for each range?

But how to I check a range?

Many Thanks
Will

Hi Will and welcome.

You check for a range like this:

if (sensor >=2500 && sensor <= 6000) {
  digitalWrite(LED1, HIGH);
} else {
  digitalWrite(LED1, LOW);
}

and so on.

You could use else if, it would be slightly more efficient, but not enough to notice!

Paul

Ahhhhh so simple when you know.

Awesome, thank you.

You might try something like:

if (sensor >= 2500 && sensor <= 6000) {
  digitalWrite(LED1, HIGH);
} else if (sensor >= 8000 && sensor <= 12000) {
  digitalWrite(LED2, HIGH);
} else if (sensor >= 13000 && sensor <= 17000) {
  digitalWrite(LED3, HIGH);
} else if (sensor > 18000) {
  digitalWrite(LED4, HIGH);
}

Please note that your ranges are not overlapping. For example, what if you read 7000, 12500, 17001?? If you want to leave those gaps, that's fine...just be aware that they exist.

You could be really flash and write:

digitalWrite(LED1, (sensor >=2500 && sensor <= 6000) ? HIGH : LOW);

Although many people would consider that less readable/maintainable!

As PaulRB points out, the ternary example:

digitalWrite(LED1, (sensor >=2500 && sensor <= 6000) ? HIGH : LOW);

and the if tests he suggested are not as efficient as the cascading series of if-else statements. In either case, if the first if statement is logic true, you still proceed to execute three more if tests even though you know they cannot be true. While the time slice is small for each test, when placed in a tight loop (e.g., the loop() function) you're talking about wasting uo to several thousand time slices per second. A few thousand here...a few thousand there...pretty soon it starts to add up.

However you write I would get rid of the 'magic' numbers in the code and make them global constants with meaningful names. It makes the code easier to understand and maintain.

const int waterLowPoint = 2500;
const int waterHighPoint = 6000;
const int beerLowPoint = 8000;
const int beerHighPoint = 12000;
const int wineLowPoint = 13000;
const int wineHighPoint = 17000;
const int mercuryLowPoint = 18000;
if (sensor >= waterLowPoint && sensor <= waterHighPoint) {
  digitalWrite(LED1, HIGH);
} else if (sensor >= beerLowPoint && sensor <= beerHighPoint) {
  digitalWrite(LED2, HIGH);
} else if (sensor >= wineLowPoint && sensor <= wineHighPoint) {
  digitalWrite(LED3, HIGH);
} else if (sensor > mercuryHighPoint) {
  digitalWrite(LED4, HIGH);
}

Obviously you choose meaningful names rather than the ones I made up !

If sensor is between 2500 - 6000 LED1 is High
If sensor is between 8000 - 12000 LED2 is High
If sensor is between 13000 - 17000 LED3 is high
If sensor is greater that 18000 LED4 is high

Testing values for several ranges is simpler if you start with the highest

led1val = 0;
led2val = 0;
led3val = 0;
led4val = 0;

if (sens > 18000) {
   led4val = 1;
}
else if (sens > 17000) {
   // undefined
}
else if (sens > 1300) {
   led3val = 1;
}
else if (sens > 12000) {
   // undefined
}
else if (sens > 8000) {
  led2val = 1;
}
else if (sens > 6000) {
  // undefined
}
else if (sens > 2500) {
   led1val = 1
}
else {
   // undefined
}

digitalWrite(led1Pin, led1val);
digitalWrite(led2Pin, led2val);
digitalWrite(led3Pin, led3val);
digitalWrite(led4Pin, led4val);

The code would be shorter if you use arrays for the pin mumbers and the led values.

...R

I wrote the above before @UKHelibob's post and I agree with him. ...R

Thank you everyone for the reply.

it is working, and it is clear there are several ways to get this to work. Still learning these things, and I like the idea of using names, makes the code read very well.

Love this little board, great for these little projects.

I absolutely agree with UKHeliBob comment about magic numbers. A common convention is to use upper case letters for such constants so they are easily identified as constants, not variables. So:

const int WATERLOWPOINT= 2500;
const int WATERHIGHPOINT= 6000;
// ...and so on...

if (sensor >= WATERLOWPOINT && sensor <= WATERHIGHPOINT) {
  digitalWrite(LED1, HIGH);
} // ...and so on...

While I don't like using the underscore character in data names, some prefer WATER_LOW_POINT. Either way, using caps makes it easy to identify constants in the code, plus, since most programmers place such constants at the top of the source code file, it tells you to look at the top of the file for the definitions.

You can also use symbolic constants, too:

#define WATERLOWPOINT 2500

The advantage of symbolic constants is that they are "typeless". That is, WATERLOWPOINT could be used in an expression with any other data type without casting. While an advantage in some cases, it does mean you lose the benefits of type checking, should you feel that is necessary.

const int mercuryLowPoint = 18000;

} else if (sensor > mercuryHighPoint) {

Hmmm...

Hmmm.., indeed, but I won't commit the sin of revising my original post and making a nonsense of your comment