No if's or while's in a switch case?

For people who actually know how to code this will seem simple, but no matter what I try I can not get an if statement, while loop, or for loop to work inside of a switch case statement.
Do I need to use a bunch of if statements instead, or put switch cases inside fewer ifs and whiles?
I am trying to build an Arduino based leveling system for my 5th wheel based on the LevelEasy commercial project, but with some improvements when finished. I built one with mercury switches, SRCs, and relays that works well but requires more user interaction than i like.
I figure I have about 300 hours trying to program it and just can't get it.The mechanical and electrical parts all check out, I have o-scopes, function generators, and years of hobby experience for that, just can't get this thing to check a switch or variable when it is in a switch case, and then change actions accordingly.
I thought a switch case was just a neater way of having a bunch of if statements, but I can't find an example of one with any other control statements inside it. Is this not possible?
Thanks

a sample function with problem

void memSet()
{

  lcd_key = read_LCD_buttons();  // read the buttons

    switch (lcd_key)               // depending on which button was pushed, we perform an action
  {
  case btnHITCH:

    {    
      hitchVHigh = average;       //Get the upper height to set hitchDifference
    }

    break;


  case btnLEVEL:                
    {  
      EEPROM.write((average / 4),1);      // save level value to eeprom
    }
    break;


  case btnTRAVEL:
    { 
      hitchVLow = average;                        //get lower hitched value
      hitchDifference = hitchVHigh - hitchVLow;   //calculate hitch offset
      EEPROM.write(hitchDifference,12);           //write offset to eeprom  

    }
    break;


   
  }


}

And another, the first one won't write to eeprom, this one ignores the pin or variable values.

    lcd_key = read_LCD_buttons();  // read the buttons

      switch (lcd_key)               // depending on which button was pushed, we perform an action
    {
    case btnHITCH:

      {    
        if (average < unHooked)
        {
          lcd.setCursor(0,0);  
          lcd.print("   HITCH   ");
          digitalWrite(upoutpin, HIGH);
        } 
      }

      break;


    case btnUP:
      {

        lcd.setCursor(0,0);
        lcd.print(" MANUAL RAISE ");   
        digitalWrite(upoutpin, HIGH);        //raise front of trailer manually

      }
      break;

    case btnDOWN:
      {
        if (digitalRead(legsw == HIGH)) 
        {
          lcd.setCursor(0,0); 
          lcd.print("MANUAL LOWER    ");
          digitalWrite(downoutpin, HIGH);
        }
      }
      break;



    case btnLEVEL:               // function here to save level value and/or level trailer
      {  

        if (resetEeprom == LOW)            // check for reset sw
        {  
          EEPROM.write (average,1);       //store the level value in eeprom
        }    
        else
        {

          if (digitalRead(legsw == HIGH && average != (levelVal *4 )))
          {
            if(average > (levelVal *4))
            {
              digitalWrite (downoutpin, HIGH );         
              lcd.setCursor(0,0);
              lcd.print("   LEVELING   ");
            }
            else
            { 
              digitalWrite(upoutpin, HIGH);
              lcd.setCursor(0,0);
              lcd.print("   LEVELING   ");
            }
          }
        }
        break;
      }

    case btnTRAVEL:
      { 
               
          if (digitalRead(legsw == HIGH))
          {
            digitalWrite(downoutpin, HIGH);   
            lcd.setCursor(0,0);  
            lcd.print("RAISING LEGS   ");    //Need limit sw to turn off
          } 
        
        break;

      }
    case btnNONE:
      {

        lcd.setCursor(0,0);  
        lcd.print("     NONE    ");
        digitalWrite(upoutpin, LOW);
        digitalWrite(downoutpin, LOW);
      }
      break;
    }

    // delay before next reading:
    //delay(100);
  }

}

These statements work as well as ever inside switch statements. If your code results don't match your expectations, then the problem must lie in either the code or the expectations. :slight_smile:

I suggest adding some Serial.print() calls to locate problems. I would start with outputting the value of lcd_key to verify that it's what you think it should be...

post your entire code, I see nothing outstanding in the examples provided at first glance (attach it as a text file if need be)

What is the value of lcd_key after it is called?
lcd_key = read_LCD_buttons();

Does it equal btnHITCH, btnLEVEL, etc, or does lcd_key = 1,2,3 etc?

Some print statements as Morris suggested will help:

lcd_key = read_LCD_buttons(); // read the buttons

Serial.print (lcd_key); // what'd you get back?

Tumbleweed:
I thought a switch case was just a neater way of having a bunch of if statements, but I can't find an example of one with any other control statements inside it. Is this not possible?

Absolutely it is possible. Post code that demonstrates the problem. Not a snippet.

Stripping your example back to compile, like this:

void memSet()
{
int lcd_key = 1;


    switch (lcd_key)               // depending on which button was pushed, we perform an action
  {
  case 1:

    {    

    }

    break;


  case 2:                
    {  

    }
    break;


  case 3:
    { 


    }
    break;


   
  }


}

void setup () {}
void loop () {}

I get no errors.

I can not get an if statement, while loop, or for loop to work inside of a switch case statement.

Your example did not have a while, if or for in it, so I don't know what it was supposed to prove.

Perhaps also post the error message?

Tumbleweed:
Do I need to use a bunch of if statements instead, or put switch cases inside fewer ifs and whiles?

Or are you saying it compiled but didn't actually work? Well it would be clearer to say so, and demonstrate conclusively in what way it didn't work.

OK, removed some comments, short enough now
will follow with more details

/*

 ADXL3xx
 
 Reads an  MMs7361 accelerometer and communicates the
 acceleration to the computer.  Using a MMS7361 analog breakout instead
 http://www.arduino.cc/en/Tutorial/ADXL3xx
 
 The circuit:
 analog 0: input for the shield buttons
 analog 1: power pin to wake accelerometer
 analog 2: x-axis
 analog 3: y-axis
 analog 4: z-axis
 digital 2: to transistor controlling 12v auto relay
 digital 3: to transistor controlling 12v auto relay 
 digital 11: leg limit switch
 digital 10: pwm output for lcd led
 */
#include <LiquidCrystal.h>
#include <EEPROM.h> 

// select the pins used on the LCD panel (RS,E,D4,D5,D6,D7)  (D10 is backlight control)
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);        // pinout for DFRobot lcd

// these constants describe the pins. They won't change:

const int upoutpin = 2;             //  up relay power
const int downoutpin = 3;            // down relay power (D4-9: LCD)
const int numReadings = 10;          //number of pin readings to average
const int dimLed = 10;         // Led brightness control
const int legsw = 11;             // 
const int resetEeprom = 12;
const int slpin = 15;                // pin to wake or power-save accelerometer

// set up averaging parameters
int readings[numReadings];      // the readings from the analog input
int index = 0;                  // the index of the current reading
int total = 0;                  // the running total
int average = 0;                // the average
int inputPin = A2;              // input for x axis
int lcd_key     = 0;            //setup switch for buttons
int adc_key_in  = 0;

#define btnHITCH     0
#define btnUP        1
#define btnDOWN      2
#define btnLEVEL     3
#define btnTRAVEL    4
#define btnNONE      6

int x,y,z;
float vx;
int levelVal = 0;                         // store level position
int hitchVLow;                 // average value when hitched
int hitchVHigh;                 // average value when raised
int hitchDifference;              // store this hitchVHigh - hitchVLow
int unHooked;                      //unhitched hieght


// read the buttons
int read_LCD_buttons()
{
  adc_key_in = analogRead(0);      // read the value from the sensor 
  // my buttons when read are centered at these valies: 0, 110, 300, 475, 600 using 3.3 aref with 1K resistor
  // we add approx 50 to those values and check to see if we are close
  if (adc_key_in > 1000) return btnNONE; // We make this the 1st option for speed reasons since it will be the most likely result
  if (adc_key_in < 50)   return btnHITCH;  
  if (adc_key_in < 180)  return btnUP; 
  if (adc_key_in < 380)  return btnDOWN; 
  if (adc_key_in < 545)  return btnLEVEL; 
  if (adc_key_in < 800)  return btnTRAVEL;       // Check values when using AREF pin at 3.3v

  return btnNONE;  // when all others fail, return this...
}    


void setup() {
  // initialize the serial communications:
  lcd.begin(16, 2);              // start the library
  lcd.setCursor(0,0);
  // analogReference(EXTERNAL);                             // set reference to 3.3v - use 3.3v power out
  pinMode(slpin, OUTPUT);                                // ready pin wake up accelerometer
  pinMode(upoutpin, OUTPUT);                              // ready up relay power pin            
  pinMode(downoutpin, OUTPUT);                            // ready down relay power pin
  pinMode (legsw, INPUT);                          // ready saftey sw 
  pinMode (dimLed, OUTPUT);                      // ready led brite control
  pinMode (resetEeprom, INPUT);                  // ready pin 12
  for (int thisReading = 0; thisReading < numReadings; thisReading++)
    readings[thisReading] = 0;



  digitalWrite(resetEeprom, HIGH);                      // set pullup resistorit
  digitalWrite(slpin, HIGH);                              // wake accelerometer
  digitalWrite(legsw, HIGH);                           // set pullup resistor
  analogWrite (dimLed, 150);                           // dim the led to save current

  levelVal = EEPROM.read(1);                         //Get stored level value
  hitchDifference = EEPROM.read(12);                 //Get stored hitch offset
}


void memSet()
{

  lcd_key = read_LCD_buttons();  // read the buttons

    switch (lcd_key)               // depending on which button was pushed, we perform an action
  {
  case btnHITCH:

    {    
      hitchVHigh = average;       //Get the upper height to set hitchDifference
    }

    break;


  case btnLEVEL:                
    {  
      EEPROM.write((average / 4),1);      // save level value to eeprom
    }
    break;


  case btnTRAVEL:
    { 
      hitchVLow = average;                        //get lower hitched value
      hitchDifference = hitchVHigh - hitchVLow;   //calculate hitch offset
      EEPROM.write(hitchDifference,12);           //write offset to eeprom  

    }
    break;   
  }
}
void loop()
{

  if (resetEeprom == LOW)
  {
    memSet();
  }
  else
  {

    // subtract the last reading:
    total = total - readings[index];         
    // read from the sensor:  
    readings[index] = analogRead(inputPin); 
    // add the reading to the total:
    total= total + readings[index];       
    // advance to the next position in the array:  
    index = index + 1;                    

    // if we're at the end of the array...
    if (index >= numReadings)              
      // ...wrap around to the beginning: 
      index = 0;                           

    // calculate the average:
    average = total / numReadings;         

    // Convert ADC values to voltages 
    // The formula for voltage conversion is v = (ADCREAD*VREF/1023)-ZGV, where ZGV is "Zero-G voltage" (voltage at 0G)
    // ZGV is found in the spec sheet and happens to be 1.62 or 1/2 VCC in our case.  Warning: you need to make the variable signed!
    // The formula for G conversion is g = v/SENSITIVITY.  The sensitvity is also found in the spec sheet and happens to be 800 mV/g here

    // Remember to make your units consistent! (g = v[V]*1000 / SEN [mV] )
    vx = (average/5.68)-levelVal;
    // gx = vx*10/8;
    // vy = (y*3.3/1023)-1.62;
    // gy = vy*10/8;
    //  vz = (z*3.3/1023)-1.62;
    //  gz = vz*10/8;

    lcd.setCursor(0,1);
    lcd.print("X = ");
    lcd.print(vx);  




    lcd_key = read_LCD_buttons();  // read the buttons

      switch (lcd_key)               // depending on which button was pushed, we perform an action
    {
    case btnHITCH:

      {    
        if (average < unHooked)
        {
          lcd.setCursor(0,0);  
          lcd.print("   HITCH   ");
          digitalWrite(upoutpin, HIGH);
        } 
      }

      break;


    case btnUP:
      {

        lcd.setCursor(0,0);
        lcd.print(" MANUAL RAISE ");   
        digitalWrite(upoutpin, HIGH);        //raise front of trailer manually

      }
      break;


    case btnDOWN:
      {
        if (digitalRead(legsw == HIGH)) 
        {
          lcd.setCursor(0,0); 
          lcd.print("MANUAL LOWER    ");
          digitalWrite(downoutpin, HIGH);
        }
      }
      break;



    case btnLEVEL:               // function here to save level value and/or level trailer
      {  

        if (resetEeprom == LOW)            // check for reset sw
        {  
          EEPROM.write (average,1);       //store the level value in eeprom
        }    
        else
        {

          if (digitalRead(legsw == HIGH && average != (levelVal *4 )))
          {
            if(average > (levelVal *4))
            {
              digitalWrite (downoutpin, HIGH );         
              lcd.setCursor(0,0);
              lcd.print("   LEVELING   ");
            }
            else
            { 
              digitalWrite(upoutpin, HIGH);
              lcd.setCursor(0,0);
              lcd.print("   LEVELING   ");
            }
          }
        }
        break;
      }

    case btnTRAVEL:
      { 
               
          if (digitalRead(legsw == HIGH))      // limit sw to turn off
          {
            digitalWrite(downoutpin, HIGH);    
            lcd.setCursor(0,0);  
            lcd.print("RAISING LEGS   ");   
          } 
        
        break;

      }
    case btnNONE:
      {

        lcd.setCursor(0,0);  
        lcd.print("     NONE    ");
        digitalWrite(upoutpin, LOW);
        digitalWrite(downoutpin, LOW);
      }
      break;
    }

    // delay before next reading:
    //delay(100);
  }

}

Thanks for the replies,
Yes it does compile. The switch case that in in the main loop function will move the linear actuator (I have actually built a small mock-up of the mechanical functions including limit switches, accelerometer, relays and actuators), but ignores the limit switches or any control statements put in to read the accelerometer . The accelerometer puts out a ten reading average to the lcd fine.

The problem with the external memset() funtion is it doesn't write to the eeprom like it is supposed to.

I know it will be simple when you tell me, that's why I've waited so long, trying to find my mistake myself.
Is there a way to put this code into a regular C IDE with a proper debugger? Stepping in while it executes sure would be nice.
Thanks again

 if (digitalRead(legsw == HIGH))

BZZZZT!if (digitalRead(legsw == HIGH && average != (levelVal *4 )))
BZZZZT!

Well spotted AWOL.

I was concentrating on why the forum hung, my name disappeared, and I was being insulted by idiots. But you stayed on focus. :slight_smile:

Thanks for the help,
obviously the syntax is wrong, where can I find intructions/examples to fix it?

As an example:

if (digitalRead(legsw == HIGH))

should be:

if (digitalRead(legsw) == HIGH)

Subtle but important.

No, the syntax is correct, otherwise the compiler would have complained.
It's the semantics that are wrong.

Thanks again,
I see what is wrong with the second example you gave too.
Sooooo embarasing, kind of like when this old southern boy goes in a nice restaurant and tries to pronounce the menu.

From one old southern boy to another:

Programming isn't about the programmer. We're all human and we all make mistakes. Learn (and believe!) that when someone finds a bug in your code, both benefit.

It's the bugs that aren't found that're the real problems. :grin:

And always remember: Most programming languages will allow you to shoot yourself in the foot, but C hands you a loaded, cocked gun with a hair-trigger!