If/Else to Switch Case help

I have a near complete project that is working fine with If statements. I have five water level indicators spread out on a plastic tank, as the water level lowers, I read the pin and print a line... simple
I'd like to clean it up and learn the Switch case but it confuses me because I have five sensors and five pins. Could someone please give a push in the right direction with a snippet of how to convert the below code to Select Case? I know it has something to do with the way I declare the variable but I'm just not sure.

const int ledpin = 13;
const int water1 = 2;
const int water2 = 3;
const int water3 = 4;
const int water4 = 5;
const int water5 = 6;
// the setup function runs once when you press reset or power the board
void setup() {
  
  Serial.begin (9600);
  pinMode(ledpin, OUTPUT);
  pinMode (water1, INPUT);
  pinMode (water2, INPUT);
  pinMode (water3, INPUT);
  pinMode (water4, INPUT);
  pinMode (water5, INPUT);
}

// the loop function runs over and over checking water level
void loop() {
  
  if (digitalRead (water1) == HIGH)
  {
  digitalWrite(ledpin, HIGH);   // turn the LED on (HIGH is the voltage level)
  Serial.println ("You're full");
  }
  else if (digitalRead (water2) == HIGH)
  {
  Serial.println ("You're 80%");
  }
  else if (digitalRead (water3) == HIGH)
  {
  Serial.println ("You're 60%");
  }
  else if (digitalRead (water4) == HIGH)
  {
  Serial.println ("You're 40");
  }
  else if (digitalRead (water5) == HIGH)
  {
  Serial.println ("You're 20%");
  }
  else 
  {
  digitalWrite(ledpin, LOW);    // turn the LED off by making the voltage LOW
  Serial.println ("You're Empty!");
  }
  delay(1500);                       // wait for a 1/2 second
  }

Is this an assignment? If not, forget about using a switch/case. The switch only works by comparing a single variable to multiple constants. That is not what you have - you're testing the results of a series of individual function calls. The problem doesn't fit the switch/case paradigm.

Hi William,

I'm a somehow advanced programmer but surely not the world best one.

Of course it can be programmed with a switch-case-statement.

But me personal I have no idea how to code it in a way that would reduce the number of lines with code.
a switch-case needs a single variable. This variable must be setup for different values
this would be still an if-statement

or maybe direct portreading and defining a list of values that can be enumerated

or defining an array to go through with a for-loop.
All solutions that are possible but will IMHO reduce readability of the code.

But maybe I'm just not experienced and / or creative enough.

best regards Stefan

New Idea: How about switching to an ultrasonic sensor measuring hight with cm-precision and calculate the volume?

You could bit-pack the pin readings, and use a simple lookup, no switch/case, no ifs.

Thank you all for the replies!
This is a personal project to monitor a Methanol tank in my trunk. Not being able to use a Switch Case makes perfect sense now. I stared at examples for an hour and couldn't get my head wrapped around it, now I know why :slight_smile:

TheMemberFormerlyKnownAsAWOL:
You could bit-pack the pin readings, and use a simple lookup, no switch/case, no ifs.

Mmmm. Well you get a sparsely populated table that way, since the indices are 0, 1, 0b11, 0b111, 0b1111, and 0b11111. That really suggests switch case handling would be better...

So you might have

int levelCode = digitalRead (water1) + digitalRead (water2)<<1 + digitalRead (water3)<<2 + digitalRead (water4)<<3 + digitalRead (water5)<<4;
...
switch (levelCode) {

But what have you really gained?

I wrote "could", not "should".

But what have you really gained?

Freedom from the tyranny of "if/else"

He he he... something like

int levelCode = digitalRead (water1) + digitalRead (water2)<<1 + digitalRead (water3)<<2 + digitalRead (water4)<<3 + digitalRead (water5)<<4;
int level = 4;
for (int i = 4; i <= 0; i--)
{
if (bitRead(levelCode, i) break;
}
int perCentFull = level * 20;
...

Actually, brainstorm... it's much easier if water1, water2 and so on are in an array. Even so, the pins are consecutive so you don't even need that! :slight_smile:

const int water1 = 2;
const int water2 = 3;
const int water3 = 4;
const int water4 = 5;
const int water5 = 6;

So

perCentFull = 0;
for (int i=0; i<5; i++)
{
if digitalRead(water1 + i) break;
else perCentFull += 20;
}

This is a general outline, it's probably got some things upside down but maybe you get the idea.

The best solution I can come up with that uses "switch/case" instead of "if/else if/else if/else if" is to convert from inputs to a percentage and then use the switch/case to act on the percentage.

const int WaterPinCount = 5;
const int WaterPins[WaterPinCount] = {2, 3, 4, 5, 6};
const int Percentages[WaterPinCount] = {100, 80, 60, 40, 20};


int OldPercentage = -1;  // Invalid value so the first reading will always be 'new'


// the setup function runs once when you press reset or power the board
void setup()
{
  Serial.begin (115200);  // 9600 baud is so 1990's


  pinMode(LED_BUILTIN, OUTPUT);


  for (int i = 0; i < WaterPinCount; i++)
  {
    pinMode(WaterPins[i], INPUT);
  }
}


// the loop function runs over and over checking water level
void loop()
{
  int percentage = 0;
  for (int i = 0; i < WaterPinCount; i++)
  {
    if (digitalRead(WaterPins[i]))
    {
      percentage = Percentages[i];
      break;
    }
  }


  // Avoid repeating the same output over and over by only doing
  // output when the value changes.
  if (percentage != OldPercentage)
  {
    OldPercentage = percentage;
    switch (percentage)
    {
      case 100:
        digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
        Serial.println ("You're full");
        break;


      case 80:
      case 60:
      case 40:
      case 20:
        Serial.print("You're ");
        Serial.print(percentage);
        Serial.println("%");
        break;


      case 0:
        digitalWrite(LED_BUILTIN, LOW);    // turn the LED off
        Serial.println ("You're Empty!");
        break;


      default:
        Serial.println("INVALID PERCENTAGE");
        break;
    }
  }
}

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