Can Switch Case statements be outside the void loop?

Hi guys,

I am very new to Arduino and am struggling at the moment on this project. I wired up a 4 by 4 keypad, a screen and 4 linear motors to my Arduino Uno. I am trying to add some controls to my linear stepper motors at the moment. I programmed it so that when the Arduino starts you have to enter values in the keypad. At the moment I have put my "switch case statement" in the "Void Loop" part of the program. However, I want it to be outside the "Void loop" and only be there when I start the Arduino. I want to use the "Hash" key take me out of some kind of "switch statement Loop."

Does anyone have advice on how I can write a "switch statement loop" that will only show up in the setup and then use the hash key to start the "Void Loop" function?

void loop{
   static int number = 0;
  char key = keypad.waitForKey();
   switch(key)
   {
       case '0'...'9':
          number *= 10;
          number += key - '0';
          break;

       case 'A':
          useForCaseA(number);
          number = 0;
          break;

       case 'B':
          useForCaseB(number);
          number = 0;     
          break;

       case 'C':
          useForCaseC(number);
          number = 0;
          break;

       case 'D':
          useForCaseD(number);
          number = 0;
          break;
          
       case '*': // Set Home Position
          break;

       case '#': // Move Motors on Position and Start Test
          break;
   }
}

Many thanks

Hi,

void aFunction(char aValue){
  switch (aValue) {
    case 'A': {
      //Your code
      break;
    }
    case 'B': {
      //Your code
      break;
    }
  }
}


void setup() {

  aFunction('A'); //this will be called once before the loop

}

void loop() {

  aFunction('A'); //this will be called on every loop

}

Jacques

I want to use the "Hash" key take me out of some kind of "switch statement Loop."

Are you looking to have a user choose from several options in setup() or will the "start" key always be # ?

Can you please explain eactly what you are trying to do ?

Your switch statement will be evaluated when it is encounter. Unless you are pressing a key on the keypad when the Arduino resets, key will be NO_KEY, for which you have no case, so the switch statement ends, and so does setup().

You could use a while statement, to loop while key == NO_KEY, with the switch statement in the body of the while statement.

Hi all,

I am trying to set up my distances that I want my linear motors to move. I want to create a loop function that will allow me to enter in values for the positions A, B, C & D and then when I press the "Hashkey" it will come out of this loop and take the stored values and put them into the motor part of my code.

This is my current code at the moment

#include <Wire.h>
#include <LCD.h>
#include<LiquidCrystal_I2C.h>
#include <Keypad.h>

int valueA = 0;
int valueB = 0;
int valueC = 0;
int valueD = 0;

const byte ROWS = 4; //four rows
const byte COLS = 4; //four colums
//define the smybols on the buttons of the keyboard

char keys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};

byte rowPins[COLS] = {2,3,4,5}; //connect to the row pinouts of the keypad
byte colPins[ROWS] = {6,7,8,9}; //connect to the colum pinouts of the keypad

//initalize an instance of class NewKeypad
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

LiquidCrystal_I2C lcd(0x3F,2,1,0,4,5,6,7,3,POSITIVE);
//0x3F is 20 by 4 LCD

LiquidCrystal_I2C lcd2(0x3E,2,1,0,4,5,6,7,3,POSITIVE);
//0x3E is 16 by 2 LCD


void setup() {
  // put your setup code here, to run once:
 //Display messages for (0x3F) 20 by 4 LCD
  lcd.backlight();
  lcd.begin(20,4);
  lcd.backlight();
  lcd.setCursor(0,0);
  lcd.print("Pin A");
  lcd.setCursor(17,0);
  lcd.print("mm");
  lcd.setCursor(0,1);
  lcd.print("Pin B");
  lcd.setCursor(17,1);
  lcd.print("mm");
  lcd.setCursor(0,2);
  lcd.print("Pin C");
  lcd.setCursor(17,2);
  lcd.print("mm");
  lcd.setCursor(0,3);
  lcd.print("MOTOR Speed");
  lcd.setCursor(17,3);
  lcd.print("RPM");


//Display messages for (0x3E) 16 by 2 LCD
  lcd2.begin(16,2);
  lcd2.backlight();
  lcd2.setCursor(0, 0);
  lcd2.print("Press # to Start");
  lcd2.setCursor(0,1);
  lcd2.print("Press * for Home");

void loop() {


   static int number = 0;
  char key = keypad.waitForKey();
   switch(key)
   {
       case '0'...'9':
          number *= 10;
          number += key - '0';
          break;

       case 'A':
          useForCaseA(number);
          number = 0;
          break;

       case 'B':
          useForCaseB(number);
          number = 0;     
          break;

       case 'C':
          useForCaseC(number);
          number = 0;
          break;

       case 'D':
          useForCaseD(number);
          number = 0;
          break;
          
       case '*': // Set Home Position
          break;

       case '#': // Move Motors on Position and Start Test
          break;

          
   }
}

void useForCaseA(int num){ 
 valueA = num;
 if((valueA >= 1) && (valueA <= 6000)){
 lcd.setCursor(10,0);
 lcd.print("       ");
 lcd.setCursor(10,0);
 lcd.print(valueA);

 }else{
 lcd.setCursor(10,0);
 lcd.print("       ");
 lcd.setCursor(10,0);
 lcd.print(valueA); 
 valueA=0;
 ErrorMessage();
 lcd.setCursor(10,0);
 lcd.print("       ");
 lcd.setCursor(10,0);
 lcd.print(valueA);
 }
}

void useForCaseB(int num){ 
 valueB = num;
 if((valueB >= 1) && (valueB <= 6000)){
 lcd.setCursor(10,1);
 lcd.print("       ");
 lcd.setCursor(10,1);
 lcd.print(valueB);

 }else{
 lcd.setCursor(10,1);
 lcd.print("       ");
 lcd.setCursor(10,1);
 lcd.print(valueB); 
 valueB=0;
 ErrorMessage();
 lcd.setCursor(10,1);
 lcd.print("       ");
 lcd.setCursor(10,1);
 lcd.print(valueB);
 }
}


void useForCaseC(int num){ 
 valueC = num;
 if((valueC >= 1) && (valueC <= 6000)){
 lcd.setCursor(10,2);
 lcd.print("       ");
 lcd.setCursor(10,2);
 lcd.print(valueC);
 
 }else{
 lcd.setCursor(10,2);
 lcd.print("       ");
 lcd.setCursor(10,2);
 lcd.print(valueC); 
 valueC=0;
 ErrorMessage();
 lcd.setCursor(10,2);
 lcd.print("       ");
 lcd.setCursor(10,2);
 lcd.print(valueC);
 }
}


void useForCaseD(int num){ 
 valueD = num;
 if((valueD >= 100) && (valueD <= 6000)){
 lcd.setCursor(13,3); 
 lcd.print("    ");
 lcd.setCursor(13,3);
 lcd.print(valueD);
 
 }else{
 lcd.setCursor(13,3);
 lcd.print("    ");
 lcd.setCursor(13,3);
 lcd.print(valueD); 
 valueD=0;
 ErrorMessage();
 lcd.setCursor(13,3);
 lcd.print("    ");
 lcd.setCursor(13,3);
 lcd.print(valueD);
 lcd.setCursor(17,3);
 lcd.print("RPM");
 }
}


void ErrorMessage(){
  //Display messages for (0x3E) 16 by 2 LCD
  lcd2.clear();
  lcd2.setCursor(2,0);
  lcd2.print("ERROR Check");
  lcd2.setCursor(1,1);
  lcd2.print("Values Entered");
  delay(10000);
  lcd2.clear();
   lcd2.begin(16,2);
  lcd2.backlight();
  lcd2.setCursor(0, 0);
  lcd2.print("Press # to Start");
  lcd2.setCursor(0,1);
  lcd2.print("Press * for Home");
  
}

Hi all,

thank you for your advice so far. I am having trouble doing a "while loop". How would I write the code to make the hash key come out of the while loop?

while ('#') {
   static int number = 0;
  char key = keypad.waitForKey();
   switch(key)
   {
       case '0'...'9':
          number *= 10;
          number += key - '0';
          break;

       case 'A':
          useForCaseA(number);
          number = 0;
          break;

       case 'B':
          useForCaseB(number);
          number = 0;     
          break;

       case 'C':
          useForCaseC(number);
          number = 0;
          break;

       case 'D':
          useForCaseD(number);
          number = 0;
          break;
          
       case '*': // Set Home Position
          break;

       case '#': // Move Motors on Position and Start Test
          break;

          
   }
}

How would I write the code to make the hash key come out of the while loop?

Pseudo code :

while (key is not '#')
{
  read key from the keypad
  do whatever you need with other input
}
while ('#') {

That's an infinite loop. '#' is non-zero, and will ALWAYS be non-zero.

Hi guys,

Thank you for your help so far. I am still a little stuck, it doesn't look like my "while loop" is working. I got an error saying "expected unqualified-id before 'while' ". I am not sure where I am going wrong. Does anyone have any advice?

const byte ROWS = 4; //four rows
const byte COLS = 4; //four colums
//define the smybols on the buttons of the keyboard

char keys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};

byte rowPins[COLS] = {2,3,4,5}; //connect to the row pinouts of the keypad
byte colPins[ROWS] = {6,7,8,9}; //connect to the colum pinouts of the keypad

//initalize an instance of class NewKeypad
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );



while (keys != '#') {
   static int number = 0;
  char key = keypad.waitForKey();
   switch(key)
   {
       case '0'...'9':
          number *= 10;
          number += key - '0';
          break;

       case 'A':
          useForCaseA(number);
          number = 0;
          break;

       case 'B':
          useForCaseB(number);
          number = 0;     
          break;

       case 'C':
          useForCaseC(number);
          number = 0;
          break;

       case 'D':
          useForCaseD(number);
          number = 0;
          break;
          
       case '*': // Set Home Position
          break;

       case '#': // Move Motors on Position and Start Test
          break;   
   }
}

Many thanks,
Suf

Your while is not in a function

Thanks AWOL,

It managed to work however, I am still getting a bit of an error. Any advice?

 while (keys != '#') {

                ^

The compiler probably doesn't like the solitary XOR operator.

 while (keys != '#') {

keys is an array. An array can never equal, or not equal, a character literal.

Hi there,

I am still having issues with the while loop. After I press the '#' key I can still go back and enter new values for each of the positions. I put the while loop in the setup and after I press the '#' key I want it to go in the Void Loop. Instead, it looks like afterwards, I can re-enter values.

How would I make my While Loop valid only in the Void Setup and after I press the '#' key, lock those values and take me into the Void Loop?

include <Wire.h>
#include <LCD.h>
#include<LiquidCrystal_I2C.h>
#include <Keypad.h>

int valueA = 0;
int valueB = 0;
int valueC = 0;
int valueD = 0;

const byte ROWS = 4; //four rows
const byte COLS = 4; //four colums
//define the smybols on the buttons of the keyboard

char keys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};

byte rowPins[COLS] = {2,3,4,5}; //connect to the row pinouts of the keypad
byte colPins[ROWS] = {6,7,8,9}; //connect to the colum pinouts of the keypad

//initalize an instance of class NewKeypad
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

LiquidCrystal_I2C lcd(0x3F,2,1,0,4,5,6,7,3,POSITIVE);
//0x3F is 20 by 4 LCD

LiquidCrystal_I2C lcd2(0x3E,2,1,0,4,5,6,7,3,POSITIVE);
//0x3E is 16 by 2 LCD


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

//Display messages for (0x3F) 20 by 4 LCD
  lcd.backlight();
  lcd.begin(20,4);
  lcd.backlight();
  lcd.setCursor(0,0);
  lcd.print("Pin A");
  lcd.setCursor(17,0);
  lcd.print("mm");
  lcd.setCursor(0,1);
  lcd.print("Pin B");
  lcd.setCursor(17,1);
  lcd.print("mm");
  lcd.setCursor(0,2);
  lcd.print("Pin C");
  lcd.setCursor(17,2);
  lcd.print("mm");
  lcd.setCursor(0,3);
  lcd.print("MOTOR Speed");
  lcd.setCursor(17,3);
  lcd.print("RPM");


//Display messages for (0x3E) 16 by 2 LCD
  lcd2.begin(16,2);
  lcd2.backlight();
  lcd2.setCursor(0, 0);
  lcd2.print("Press # to Start");
  lcd2.setCursor(0,1);
  lcd2.print("Press * for Home");



while (keys != '#') {
   static int number = 0;
  char key = keypad.waitForKey();
   switch(key)
   {
       case '0'...'9':
          number *= 10;
          number += key - '0';
          break;

       case 'A':
          useForCaseA(number);
          number = 0;
          break;

       case 'B':
          useForCaseB(number);
          number = 0;     
          break;

       case 'C':
          useForCaseC(number);
          number = 0;
          break;

       case 'D':
          useForCaseD(number);
          number = 0;
          break;
          
       case '*': // Set Home Position
          break;

       case '#': // Move Motors on Position and Start Test
          StartMessage();
          loop();
          break;   
   }
}
}
void loop() {
//Another Code
}
void StartMessage() {
  lcd2.clear();
  lcd2.begin(16,2);
  lcd2.backlight();
  lcd2.setCursor(0, 0);
  lcd2.print("No of Cycles:");
  }
  
void useForCaseA(int num){ 
 valueA = num;
 if((valueA >= 1) && (valueA <= 6000)){
 lcd.setCursor(10,0);
 lcd.print("       ");
 lcd.setCursor(10,0);
 lcd.print(valueA);

 }else{
 lcd.setCursor(10,0);
 lcd.print("       ");
 lcd.setCursor(10,0);
 lcd.print(valueA); 
 valueA=0;
 ErrorMessage();
 lcd.setCursor(10,0);
 lcd.print("       ");
 lcd.setCursor(10,0);
 lcd.print(valueA);
 }
}

void useForCaseB(int num){ 
 valueB = num;
 if((valueB >= 1) && (valueB <= 6000)){
 lcd.setCursor(10,1);
 lcd.print("       ");
 lcd.setCursor(10,1);
 lcd.print(valueB);

 }else{
 lcd.setCursor(10,1);
 lcd.print("       ");
 lcd.setCursor(10,1);
 lcd.print(valueB); 
 valueB=0;
 ErrorMessage();
 lcd.setCursor(10,1);
 lcd.print("       ");
 lcd.setCursor(10,1);
 lcd.print(valueB);
 }
}


void useForCaseC(int num){ 
 valueC = num;
 if((valueC >= 1) && (valueC <= 6000)){
 lcd.setCursor(10,2);
 lcd.print("       ");
 lcd.setCursor(10,2);
 lcd.print(valueC);
 
 }else{
 lcd.setCursor(10,2);
 lcd.print("       ");
 lcd.setCursor(10,2);
 lcd.print(valueC); 
 valueC=0;
 ErrorMessage();
 lcd.setCursor(10,2);
 lcd.print("       ");
 lcd.setCursor(10,2);
 lcd.print(valueC);
 }
}


void useForCaseD(int num){ 
 valueD = num;
 if((valueD >= 100) && (valueD <= 600)){
 lcd.setCursor(13,3); 
 lcd.print("    ");
 lcd.setCursor(13,3);
 lcd.print(valueD);
 
 }else{
 lcd.setCursor(13,3);
 lcd.print("    ");
 lcd.setCursor(13,3);
 lcd.print(valueD); 
 valueD=0;
 ErrorMessage();
 lcd.setCursor(13,3);
 lcd.print("    ");
 lcd.setCursor(13,3);
 lcd.print(valueD);
 lcd.setCursor(17,3);
 lcd.print("RPM");
 }
}


void ErrorMessage(){
  //Display messages for (0x3E) 16 by 2 LCD
  lcd2.clear();
  lcd2.setCursor(2,0);
  lcd2.print("ERROR Check");
  lcd2.setCursor(1,1);
  lcd2.print("Values Entered");
  delay(10000);
  lcd2.clear();
  lcd2.begin(16,2);
  lcd2.backlight();
  lcd2.setCursor(0, 0);
  lcd2.print("Press # to Start");
  lcd2.setCursor(0,1);
  lcd2.print("Press * for Home");
}

Many thanks again

while (keys != '#')keys is an array.
'#' is a single character.
The comparison makes no sense.

How would I make my While Loop valid only in the Void Setup and after I press the '#' key, lock those values and take me into the Void Loop?

You'd sound a lot less like a clueless dweeb if you stopped referring to setup() and loop() as voids. They are NOT voids any more than digitalRead() is an int.

They are FUNCTIONS.

Your code does NOT have a Setup() function, a Loop() function or a While loop. It has a setup() function, a loop() function, and a while loop.

You need to define EXACTLY what it is you are waiting for. keys is an array. It is NOT possible, or even meaningful, to compare it with the literal '#'.

It doesn't even make sense to wait for a key to be pressed, since you are already blocking waiting for keys to be pressed.

You already have some purpose defined for all 16 keys, so you can't keep setup() from ending until a specific key is pressed.

Hi PaulS,

I got it to work now :). I am still new to coding and obviously have a long way to go. Sorry if at times I don't make any sense.:confused: .

Thank you for your help and advice. I declared "key" as a char in the global variable. It works now

char key = 'z';

void setup() {
while (key != '#') {
  static int number = 0;
  key = keypad.waitForKey();
   switch(key)
   {
       case '0'...'9':
          number *= 10;
          number += key - '0';
          break;

       case 'A':
          useForCaseA(number);
          number = 0;
          break;

       case 'B':
          useForCaseB(number);
          number = 0;     
          break;

       case 'C':
          useForCaseC(number);
          number = 0;
          break;

       case 'D':
          useForCaseD(number);
          number = 0;
          break;
          
       case '*': // Set Home Position
       //home();
          break;

       case '#': // Move Motors on Position and Start Test
          CycleMessage();
          //start();
          break;

   }
   }

}