Multiple if() ranges with counter

Moderately new to arduino. My first post here. Not my first project, and I'm typically capable of understanding and digging around until I figure out why things are not working and how to make them work, but this seemingly refuses to work logically. Or maybe I'm crazy... Not sure yet.

manifold - input from sensor that's translated to a value that is from -10 to 15. (logic within this works perfectly, in use with another project that's live.)
counter - controlled by two buttons for up/down. Range of values is limited to 5 through 10, starts by default at 5. pressing one button adds one, and it stays. vice versa for the other button. (working perfectly.)
dutyValue - currently an irrelevant number referenced purely for seeing which if() statement is being activated (printed on a OLED display), but will eventually be a logical duty cycle value.

Whats happening:
If manifold = 4.2, then dutyValue = 245.
If manifold = 5.3, then dutyValue = 245.
If manifold = 7.6, then duty value = 247.

it will follow the counter. if i change counter to 6 - 10, then it follows the respective duty within the 245-250 outputs

why is it disregarding the very first group of code?
if I comment out the "manifold > 5 line", then it jumps to the next one and outputs 246.

i realize its very likely that there is error in my logic, but i cant exactly figure out what.

if its not evident what I'm after...
if manifold sees 6, counter is on 5, duty cycle sent to solenoid to bring manifold to 5.
if manifold sees 15, counter on 5, duty cycle sent to solenoid to bring manifold to 5.
if manifold sees 5, counter on 8, duty cycle sent to solenoid to bring manifold to 8.

Basically controlling solenoid via duty cycle to bring manifold to the specified value by the counter.

The ultimate goal is to ONLY show 246 when manifold is between 6 and 6.9, and so on respectively. if its above 6.9, and counter is on 5, then duty cycle will drop to shut off adding manifold pressure.

if (manifold < 5 && counter == 5) {dutyValue = 5;}

if (manifold < 6 && counter == 6) {dutyValue = 6;}

if (manifold < 7 && counter == 7) {dutyValue = 7;}

if (manifold < 8 && counter == 8) {dutyValue = 8;}

if (manifold < 9 && counter == 9) {dutyValue = 9;}

if (manifold <10 && counter ==10) {dutyValue = 10;}


if (manifold >  5 && manifold < 5.9 || counter == 5)  {dutyValue = 245;}

if (manifold >  6 && manifold < 6.9 || counter == 6)  {dutyValue = 246;}

if (manifold >  7 && manifold < 7.9 || counter == 7)  {dutyValue = 247;}

if (manifold >  8 && manifold < 8.9 || counter == 8)  {dutyValue = 248;}

if (manifold >  9 && manifold < 9.9 || counter == 9)  {dutyValue = 249;}

if (manifold > 10 || counter == 10) {dutyValue = 250;}

What am I doing wrong? I've also tried the code below, and a few other things, but makes no difference. Am I asking too much of the if() with having so much going on and different ranges? If i comment out the 2nd group of ifs, then the first set works exactly as expected.

I'm sorry if this is confusing. I imagine there may be other ways to do this, but this made some sort of sense in my head. My luck I'm probably completely out in left field somewhere and there's a super simple and logical solution that'll take 5 minutes to code.

if (5 > manifold < 5.9 || counter == 5)  {dutyValue = 245;}

I have not looked in detail but I suspect that more than one of the tests returns true. If so then the last one found to be true will be acted upon

How about introducing an else between the tests so that only the first one found to be true is acted upon ?

if (5 > manifold < 5.9 || counter == 5)  {dutyValue = 245;}

is certainly wrong and should be

if ((5 > manifold  && manifold < 5.9) || counter == 5)  {dutyValue = 245;}

Note that I have also added an extra set of brackets to avoid any possibility of confusion as to the precedence of operators which I can never remember

Nothing takes five minutes :slight_smile:
As @UKHeliBob points out, the problem is likely related to order of operations. You should surround every comparison with parentheses. Never rely on remembering the order: it's not good practice.

Here's an alternative representation. Not tested but you can probably tweak it into shape.

#include <float.h>

typedef struct tagParams
{
 float lower;
 float upper;
 int counter;
 int output;
} paramsStruct;

paramsStruct params[] = 
{
    {5, 0, 5,5},
    {6, 0, 6,6},
    {7, 0, 7,7},
    {8, 0, 8,8},
    {9, 0, 9,9},
    {10,0, 10,10},

    {5,  5.9, 5, 245},
    {6,  6.9, 6, 246},
    {7,  7.9, 7, 247},
    {8,  8.9, 8, 246},
    {9,  9.9, 9, 249},
    {10, FLT_MAX, -1, 250}
};

const int NPARAMS = 12;
const int OR_LIMIT = 6;

void setup() 
{
    // put your setup code here, to run once:

}

void loop() 
{
    float dutyValue = 0.0;
    int counter;
    float manifold;
    
    for (int i =0; i < NPARAMS; i++)
    {
        if (i < OR_LIMIT)
        {
            if ( (manifold < params[i].lower) && (counter == params[i].counter))
            {
                dutyValue = params[i].output;
                break; 
            }
        }
        else
        {
            if ( (manifold > params[i].lower) && (manifold < params[i].upper) || ( counter == params[i].counter))
            {
                dutyValue = params[i].output;
                break;
            }
        }
    }

}

which "group"?

shouldn't your code be structured more like this, where counter determines the thresholds and outputs?

int
comparator (
    int manifold,
    int counter )
{
    if (5 == count) {
        if (manifold < -5)
            return 501;
        if (manifold <  0)
            return 502;
        if (manifold <  5)
            return 503;
        if (manifold <  10)
            return 504;
        return 505;
    }

    if (6 == count) {
        if (manifold < -5)
            return 601;
        if (manifold <  0)
            return 602;
        if (manifold <  5)
            return 603;
        if (manifold <  10)
            return 604;
        return 605;
    }

    if (7 == count) {
        if (manifold < -5)
            return 701;
        if (manifold <  0)
            return 702;
        if (manifold <  5)
            return 703;
        if (manifold <  10)
            return 704;
        return 705;
    }

    // ...

The reason is the part

|| counter == x) { // with x between 5 and 10

in the second group. Whatever the outcome of the first group is will be eliminated by the second group as counter has definitely a value between 5 and 10.

Instead of the second group (as it is now) you could check whether manifold is greater 10. If yes set dutyValue accordingly.

If not check if manifold is greater than counter. If yes, set the (new) integer variable index to integer(manifold) if not set index to counter.

Then use the value of index to set the dutyValue .

Hope that's clear enough... :wink:

[Edit]: Had some time now to realize a test of the logic of post # 1. Not sure if there is a flaw but the test samples look alright:

Sketch:

/*
  Forum:  Forum: https://forum.arduino.cc/t/multiple-if-ranges-with-counter/1215664/5
  Wokwi: https://wokwi.com/projects/387921777848912897

*/
void setup() {
  Serial.begin(115200);
  float mani = 5.8;
  int count  = 5;
  group1Old(mani,count);
  group1New(mani,count);
  group2Old(mani,count);
  group2New(mani,count);
}

void loop() {
  // put your main code here, to run repeatedly:

}



void group1Old(float manifold, int counter) {
  int dutyValue = 0;
  if (manifold < 5 && counter == 5) {
    dutyValue = 5;
  }
  if (manifold < 6 && counter == 6) {
    dutyValue = 6;
  }
  if (manifold < 7 && counter == 7) {
    dutyValue = 7;
  }
  if (manifold < 8 && counter == 8) {
    dutyValue = 8;
  }
  if (manifold < 9 && counter == 9) {
    dutyValue = 9;
  }
  if (manifold < 10 && counter == 10) {
    dutyValue = 10;
  }
  Serial.print(manifold);
  Serial.print("\t");
  Serial.print(counter);
  Serial.print("\t");
  Serial.println(dutyValue);
}

void group2Old(float manifold, int counter) {
  int dutyValue = 0;
  if (manifold >  5 && manifold < 5.9 || counter == 5)  {
    dutyValue = 245;
  }
  if (manifold >  6 && manifold < 6.9 || counter == 6)  {
    dutyValue = 246;
  }
  if (manifold >  7 && manifold < 7.9 || counter == 7)  {
    dutyValue = 247;
  }
  if (manifold >  8 && manifold < 8.9 || counter == 8)  {
    dutyValue = 248;
  }
  if (manifold >  9 && manifold < 9.9 || counter == 9)  {
    dutyValue = 249;
  }
  if (manifold > 10 || counter == 10) {
    dutyValue = 250;
  }
  Serial.print(manifold);
  Serial.print("\t");
  Serial.print(counter);
  Serial.print("\t");
  Serial.println(dutyValue);
}


void group1New(float manifold, int counter) {
  int dutyValue = 0;
  if (manifold < counter ) {
    dutyValue = counter;
  }
  Serial.print(manifold);
  Serial.print("\t");
  Serial.print(counter);
  Serial.print("\t");
  Serial.println(dutyValue);
};


void group2New(float manifold, int counter) {
  int dutyValue = 0;
  int index = counter;
  if (manifold > counter) {
    index = manifold;
  }
  if (index >= 10) {
    dutyValue = 250;
  } else {
    dutyValue = 245 + (index-5);
  }
  Serial.print(manifold);
  Serial.print("\t");
  Serial.print(counter);
  Serial.print("\t");
  Serial.println(dutyValue);
}

See Wokwi: https://wokwi.com/projects/387921777848912897

Basically there are four functions:

  • group1Old should hopefully print the results of your logic from post #1

  • group1New should produce the same results but with less lines of code

  • group2Old should hopefully print the results of your logic from post #1

  • group2New should produce the same results but with less lines of code

group1New:

  int dutyValue = 0;
  if (manifold < counter ) {
    dutyValue = counter;
  }

group2New

  int dutyValue = 0;  
  int index = counter;
  if (manifold > counter) {
    index = manifold;
  }
  if (index >= 10) {
    dutyValue = 250;
  } else {
    dutyValue = 245 + (index-5);
  }

The results of group1 are irrelevant as group2 will set dutyValue anyway.
I am not sure if the outcome is what you really want and hope I did not make a mistake ... :wink:

@cedarlakeinstruments, your code works EXACTLY like I wanted. I had to do a little rearranging and sort through a few things to make it work with the rest of my existing code outside of this function, but otherwise works spot on beautifully. THANK YOU!!!

To be completely honest, I haven't dug into exactly how this chunk of code works just yet, but I soon will, and will expand upon it when/if the need arises.

I don't know if there's any form of kudos, appreciation, or whatnot in this forum, but either way I'd happily PayPal you some coin for your efforts, if anything at least for a beer/coffee to enjoy.

Just happy that I could help.

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.