loading

In this Instructable, we'll be going over the "switch()" statement and it's use in programming. The switch statement is a powerful tool for organizing your program, easily allow you to move through complex flowcharts.

In our switch statement, we'll be going over some different input options to create a sequence of events. We'll start easy, with some timing delays to move actuators, then move to processing some inputs to trigger the next stage of motion. Finally, we'll put everything we learned together to make a simulated factory line!

For this project, we will need:

- Ardunio Board

- Actuator

- Actuator with Potentiometer

- 2x MegaMoto motor shield

- Breadboard

- Push buttons for inputs (you can use a wire connected to ground to simulate buttons)

- Potentiometer (10k preferred, any value works)

- LEDs (can use the built in LED on pin 13)

Let's get started!

Step 1: The Switch() Statement

Before we dive into the coding, we need to understand what we are working with. The basics of the switch() statement is that you watch a variable, and depending what the variable's value is, a different case in the switch() is activated.

This property makes it very easy to make a program pointer that will move through your code, applying all the appropriate inputs and outputs at the correct time. There is also a default case, so that you can put a section of the program to happen when the variable you are watching does not match one of the programmed cases.

For the first example, we'll have a passive code. By watching the serial monitor, you can see the program count to 5 over 5 seconds. The switch statement sits in each case until 1 second has passed, then moves to the next. See the attached code, read the comments, and upload it to see how it works before moving on.

Since these are just test programs, you can leave the board plugged into the computer so the Arduino can receive power.

/*  This code is to show the basic workings of a switch statement.  It counts
  to 10 in the serial monitor using a delay.</p><p>  Written by Progressive Automations
  Sept 21, 2015

  This code is in the public domain
 */
int programCount = 0;//variable to move through the program

void setup() {
  Serial.begin(9600);// initialize serial communication:
  programCount = 0;//start at the beginning
}//end setup

void loop() {

  switch (programCount) {
    case 0:
      delay(1000);//wait 1 second
      Serial.println("0");//print the number
      programCount = 1;
      break;

    case 1:
      delay(1000);//wait 1 second
      Serial.println("1");//print the number
      programCount = 2;
      break;

    case 2:
      delay(1000);//wait 1 second
      Serial.println("2");//print the number
      programCount = 3;
      break;

    case 3:
      delay(1000);//wait 1 second
      Serial.println("3");//print the number
      programCount = 4;
      break;

    case 4:
      delay(1000);//wait 1 second
      Serial.println("4");//print the number
      programCount = 5;
      break;

    case 5:
      delay(1000);//wait 1 second
      Serial.println("5");//print the number
      programCount = 6;
      break;

    default:
      Serial.print("Counting complete");
      while(1); //freeze the program here

  }//end switch
}//end loop

Step 2: Adding Basic Digital Inputs

Now that we know the basics of a switch statement, we can add in a basic digital input. We'll use a button to trigger the movement to the next state.

In the first case, we'll use a counter to store how long the button has been pressed. Once it has been held for 5 seconds, we'll move to the next state. Watch the serial monitor to see when the program is done.

See the code below, then upload it to see how it works before moving to the next step.

Since these are just test programs, you can leave the board plugged into the computer so the Arduino can receive power.

/*  This code is to show how a digital input can move through cases
  in a switch statement.  The button must be pressed 5 times to move
  on.

  Written by Progressive Automations
  Sept 21, 2015

  This code is in the public domain
 */
const int button = 5;//attach the button on pin 5 
int programCount = 0;//variable to move through the program
int buttonCount = 0;//variable to hold the button presses

int buttonState = 1;//variable to hold the state of the button

void setup() {
  Serial.begin(9600);// initialize serial communication:
  programCount = 0;//start at the beginning
  buttonCount = 0;//set to 0 to start
  pinMode(button,INPUT);//set the button as an input
  digitalWrite(button, HIGH);//enable internal pullup resistor
  Serial.println("Hold the button for 5 seconds to complete the program");
}//end setup

void loop() {

  switch (programCount) {
    case 0:
      buttonState = digitalRead(button);
      if (buttonState==0)
      {
        buttonCount = buttonCount+1;//count up every time the button is pressed
        delay(1);//small delay for counting milliseconds
      }
      if (buttonCount == 5000) programCount = 1;//once the button is pressed enough times, move on
      break;

    case 1:
      
      Serial.println("Button has been held for 5 seconds");//print the number
      delay(1000);
      programCount = 2;
      break;

    default:
      Serial.println("Program complete");
      while(1); //freeze the program here

  }//end switch
}//end loop

Step 3: Adding Basic Analog Inputs

The next input we'll try is an analog input. Most sensors give some sort of analog signal, for this example we will be using a potentiometer. The code will read the potentiometer, and only advance once the desired value is reached.

Wire the potentiometer according to the diagram, and upload the code below.

Since these are just test programs, you can leave the board plugged into the computer so the Arduino can receive power.

/*  This code is to show how an analog input can be used to move through a
  switch statement.  The potentiometer must be moved to the desired value
  before advancing to the next stage in the program.

  Written by Progressive Automations
  Sept 21, 2015

  This code is in the public domain
 */
const int pot = A0;//attach the pot to pin A0
int potValue = 0;//variable to hold the pots reading
int programCount = 0;//variable to move through the program

void setup() {
  Serial.begin(9600);// initialize serial communication:
  pinMode(pot, INPUT); //set the pot as an input
  programCount = 0;//start at the beginning of the program
  Serial.println("Move the potentiometer to the desired locations to advance");
}//end setup

void loop() {

  switch (programCount) {
    case 0:
      potValue = analogRead(pot);//read the pot's value
      Serial.println("Move the potentiometer fully to one side to get the max reading");
      while (potValue <= 1000)//1023 is max value
      {
        potValue = analogRead(pot);//read the pot's value
        delay(10);//small delay between readings
      }
      Serial.println(potValue);//show what the reading is
      Serial.println("One limit reached!");
      Serial.println("");//print an extra line

      if (potValue >= 1000) programCount = 1;//once the value is at the desired position, move on
      break;

   case 1:

      potValue = analogRead(pot);//read the pot's value
      Serial.println("Move the potentiometer to the middle");
      while (potValue >= 500)//~512 is the middle
      {
        potValue = analogRead(pot);//read the pot's value
        delay(10);//small delay between readings
      }
      Serial.println(potValue);//show what the reading is
      Serial.println("Middle position reached!");
      Serial.println("");//print an extra line

      if (potValue <= 500) programCount = 2;//once the value is at the desired position, move on
      break;

    case 2:
      potValue = analogRead(pot);//read the pot's value
      Serial.println("Move the potentiometer fully to the other side to get the min reading");
      while (potValue >= 10)//0 is min value
      {
        potValue = analogRead(pot);//read the pot's value
        delay(10);//small delay between readings
      }
      Serial.println(potValue);//show what the reading is
      Serial.println("Final limit reached!");
      Serial.println("");//print an extra line

      if (potValue <= 10) programCount = 3;//once the value is at the desired position, move on
      break;

    default:
      Serial.println("Program complete");
      while (1); //freeze the program here

  }//end switch
}//end loop

Step 4: Adding Outputs

Now that we've tested different inputs, we can see how outputs can be used in the switch() statements as well. We will use the MegaMoto to control an actuator to extend and retract. This example is similar to the first example, we're just using time delays.

See the wiring diagram, and upload the code. See the MegaMoto Instructable for more detail information about the motor controller. While the program is running, the motor will be moving, and you can watch the serial monitor to see what is happening.

Since these are just test programs, you can leave the board plugged into the computer so the Arduino can receive power.

/*  This code is to show how outputs are used in a switch statement. The code
  moves an actuator in and out at varying speeds, according to the sequence.

  Written by Progressive Automations
  Sept 21, 2015

  This code is in the public domain
 */
 const int enable = 8;
 const int PWMA = 11;
 const int PWMB = 3;//pins for the MegaMoto
 
int programCount = 0;//variable to move through the program

void setup() {
  Serial.begin(9600);// initialize serial communication:
  programCount = 0;//start at the beginning
  pinMode(enable, OUTPUT);
  pinMode(PWMA, OUTPUT);
  pinMode(PWMB, OUTPUT);
}//end setup

void loop() {

  switch (programCount) {
    case 0:
      digitalWrite(enable, HIGH);//enable the control board
      Serial.println("Motor moving forwards at full speed");
      analogWrite(PWMA, 255);
      analogWrite(PWMB, 0);//set the speed of the actuator
      delay(5000);//Move for 5 seconds
      programCount = 1;
      break;

    case 1:
      Serial.println("Motor moving backwards at full speed");
      analogWrite(PWMA, 0);
      analogWrite(PWMB, 255);//set the speed of the actuator
      delay(5000);//Move for 5 seconds
      programCount = 2;
      break;

    case 2:
      Serial.println("Motor moving forwards at half speed");
      analogWrite(PWMA, 128);
      analogWrite(PWMB, 0);//set the speed of the actuator
      delay(3000);//Move for 3 seconds
      programCount = 3;
      break;

    case 3:
      Serial.println("Motor moving forwards at full speed");
      analogWrite(PWMA, 255);
      analogWrite(PWMB, 0);//set the speed of the actuator
      delay(2000);//Move for 2 seconds
      programCount = 4;
      break;

    case 4:
     Serial.println("Motor moving backwards at full speed");
      analogWrite(PWMA, 0);
      analogWrite(PWMB, 255);//set the speed of the actuator
      delay(2000);//Move for 2 seconds
      programCount = 5;
      break;

    case 5:
      Serial.println("Motor moving backwards at half speed");
      analogWrite(PWMA, 0);
      analogWrite(PWMB, 128);//set the speed of the actuator
      delay(3000);//Move for 3 seconds
      programCount = 6;
      break;

    default:
      Serial.print("Movement complete");
      while(1); //freeze the program here

  }//end switch
}//end loop

Step 5: Putting It All Together

Since we've now seen all the inputs and outputs in action, let's put it all together!

We will simulate a part moving along an assembly line, with different actions being applied. We will use limit switches and the potentiometer feedback from the actuator. This is the sequence we will follow:

- Wait for push button input to start the cycle

- Extend the first actuator at full speed for 5 seconds to move the part into place

- Turn on the LED to simulate a washing cycle being started

- Wait 5 seconds for washing, then turn off LED

- Retract the first actuator at half speed for 10 seconds to dry the part

- Extend the second actuator at full speed to position 1

- Turn on the other LED, wait 2 seconds, turn off the LED

- Extend the second actuator at full speed to position 2

- Turn on the other LED, wait 2 seconds, turn off the LED

- Extend the second actuator at full speed to position 3

- Turn on the other LED, wait 2 seconds, turn off the LED

- Retract the second actuator at full speed for 5 seconds to complete the cycle.

- Wait for push button input to restart the cycle

Wire the system according to the diagram, and upload the code to see how it works!

Since these are just test programs, you can leave the board plugged into the computer so the Arduino can receive power.

/*  This code is to show how outputs are used in a switch statement. The code
  moves an actuator in and out at varying speeds, according to the sequence.

  Written by Progressive Automations
  Sept 21, 2015

  This code is in the public domain
 */
const int enable1 = 8;
const int PWMA1 = 11;
const int PWMB1 = 3;//pins for the first MegaMoto(Actuator)

const int enable2 = 12;
const int PWMA2 = 9;
const int PWMB2 = 10;//pins for the second MegaMoto(Actuator)

const int potFeedback = A0;//pin for the second actuators potentiometer

const int LED1 = 7;
const int LED2 = 13;//two pins for LEDs

const int button = 6;//restart button

int programCount = 0;//variable to move through the program
int buttonState = 1;//vairable to store the state of the button,initialise as HIGH

int pos1 = 100;
int pos2 = 500;
int pos3 = 1000;//three positions to move to

void setup() {
  Serial.begin(9600);// initialize serial communication:
  programCount = 0;//start at the beginning

  pinMode(enable1, OUTPUT);
  pinMode(PWMA1, OUTPUT);
  pinMode(PWMB1, OUTPUT);//set first MegaMoto as outputs

  pinMode(enable2, OUTPUT);
  pinMode(PWMA2, OUTPUT);
  pinMode(PWMB2, OUTPUT);//set second MegaMoto outputs

  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT);//set LED's as outputs

  pinMode(button, INPUT);//set button as input
  digitalWrite(button, HIGH);//enable internal pullup

  pinMode(potFeedback, INPUT);//set potentiometer as input
}//end setup

void loop() {

  switch (programCount) {

    case 0:
      
      digitalWrite(enable1,LOW);
      digitalWrite(enable2,LOW);//disable both control boards so the actuators cant move
      Serial.println("Waiting to start sequence");
      while (digitalRead(button) == 1){}//wait here until button is pressed 
      programCount = 1;//once button is pressed, advance
      break;

    case 1:
      digitalWrite(enable1, HIGH);//enable the first actuators control board
      Serial.println("First Actuator moving forwards at full speed");
      analogWrite(PWMA1, 255);
      analogWrite(PWMB1, 0);//set the speed of the actuator
      delay(5000);//Move for 5 seconds
      analogWrite(PWMA1, 0);
      analogWrite(PWMB1, 0);//stop the actuator
      programCount = 2;
      break;

    case 2:
      Serial.println("Washing the part");
      digitalWrite(LED1, HIGH);//turn on LED
      programCount = 3;
      break;

    case 3:
      delay(5000);
      Serial.println("Washing complete");
      digitalWrite(LED2, LOW);//turn off LED
      programCount = 4;
      break;

    case 4:
      Serial.println("First Actuator moving backwards at half speed");
      analogWrite(PWMA1, 0);
      analogWrite(PWMB1, 128);//set the speed of the actuator
      delay(10000);//Move for 10 seconds
      analogWrite(PWMA1, 0);
      analogWrite(PWMB1, 0);//stop the actuator
      programCount = 5;
      break;

    case 5:
      Serial.println("Second Actuator moving at full speed to Position 1");
      digitalWrite(enable2,HIGH);//enable the second actuators control board
      while (analogRead(potFeedback) <= pos1)
      {
        analogWrite(PWMA2, 255);
        analogWrite(PWMB2, 0);//set the speed of the actuator
      }
      analogWrite(PWMA2, 0);
      analogWrite(PWMB2, 0);//stop the actuator
      programCount = 6;
      break;

    case 6:
      Serial.println("First decal being applied");
      digitalWrite(LED2, HIGH);
      delay(2000);
      digitalWrite(LED2, LOW);
      programCount = 7;
      break;

    case 7:
      Serial.println("Second Actuator moving at full speed to Position 2");
      while (analogRead(potFeedback) <= pos2)
      {
        analogWrite(PWMA2, 255);
        analogWrite(PWMB2, 0);//set the speed of the actuator
      }
      analogWrite(PWMA2, 0);
      analogWrite(PWMB2, 0);//stop the actuator
      programCount = 8;
      break;

    case 8:
      Serial.println("Second decal being applied");
      digitalWrite(LED2, HIGH);
      delay(2000);
      digitalWrite(LED2, LOW);
      programCount = 9;
      break;

    case 9:
      Serial.println("Second Actuator moving at full speed to Position 3");
      while (analogRead(potFeedback) <= pos3)
      {
        analogWrite(PWMA2, 255);
        analogWrite(PWMB2, 0);//set the speed of the actuator
      }
      analogWrite(PWMA2, 0);
      analogWrite(PWMB2, 0);//stop the actuator
      programCount = 10;
      break;

    case 10:
      Serial.println("Third decal being applied");
      digitalWrite(LED2, HIGH);
      delay(2000);
      digitalWrite(LED2, LOW);
      programCount = 11;
      break;

    case 11:
      Serial.println("Second Actuator moving backwards at full speed");
      analogWrite(PWMA2, 0);
      analogWrite(PWMB2, 255);//set the speed of the actuator
      delay(5000);//Move for 5 seconds
      analogWrite(PWMA2, 0);
      analogWrite(PWMB2, 0);//stop the actuator
      Serial.println("Sequence Complete");
      Serial.println("");
      Serial.println("");//print some blank spaces to make serial monitor more read-able
      programCount = 0;//loop back to the beginning
      break;

    default:
      Serial.print("Error");
      while (1); //freeze the program here

  }//end switch
}//end loop

Step 6: Conclusion

In this Instructable, we learned how a switch() statement can be used to control the flow of a program. We went over digital inputs, analog inputs, and outputs, and finished with a simulated system that brought it all together. This code can be modified to make your actuators follow any sequence of events, using a variety of inputs and outputs.

If you'd like to take a look at our selection of linear actuators, motions control systems and microcontrollers then please visit us at www.progressiveautomations.com for all your actuator needs! We can even build a custom actuator or control system for you based on your own custom specifications with the help of our highly trained staff of engineers. You can learn more about the custom order process right here!

Follow, Like and Subscribe!

Twitter - twitter.com/ProgAutoInc

Facebook - www.facebook.com/ProgressiveAutomations

Youtube - www.youtube.com/user/MrActuators

<p>should have made it set programCount to -1 in case 5. and it looks like your code would stay forever hung at the while statement. should make that a variable or bool that you can set based on something.</p>
<p>also a second actuator would be needed to close throttle...wch</p>
<p>ok I see your point ,however this program with a few mods could be used for an auto stop system in a car, sonic sensors on the front and /or rear bumper would sense distance to object/auto speed and activators would push brake pedal if speed exceeded preset amount...WCH </p>
<p>Hi Guys,</p><p>I just finished the first version of my 'Automaton' framework which works on the same state-machine principles as this instructable, like you I've become interested in state machines as a way of multitasking Arduino's. Automaton has about 0 users so far, and I'd love to get some feedback on it from people who are working who are interested in state machines and the like. </p><p>I had similar design decisions to make. I went for the enums and the state changes are controlled by a state transition table contained in a class. The switch statement from this instructable is was broken up per state machine (object) and split in events and actions. That makes for a nice modular approach that lends itself very well to multitasking. </p><p><a href="https://github.com/tinkerspy/Automaton" rel="nofollow">https://github.com/tinkerspy/Automaton</a></p><p>Documentation &amp; tutorial:<br></p><p><a href="https://github.com/tinkerspy/Automaton/wiki" rel="nofollow">https://github.com/tinkerspy/Automaton/wiki</a></p><p>You should also be able to install it via the Arduino Library manager. I'd appreciate it if some of you could have a look and tell me what you think.</p><p>Thanks,</p><p>Tinkerspy</p><p>@ProgressiveAuto1: if you think I'm hijacking your instructable I apologize, in that case feel free to delete this post</p><br>
<p>No worries, it looks like a cool project!</p>
<p>Another name for such a code block is &quot;state machine&quot; , and the switch statement statement is a good to implement one.</p><p>One &quot;Pro Tip&quot; is to make the cases 10,20,30... instead of 1,2,3... At least when you first write the code. That way when you realize there needed to be 2 more steps in between, you can call them 23 and 27, and still have the steps happening in numerical order. If you don't have the steps happen in numerical sequence, the code becomes very hard to maintain, as it is essentially another form of spaghetti code.</p>
<p>Excellent ProTip. That's far easier then having to go back and re-number every state when you add new ones.</p>
A better protip would be to use an enumeration. <br><br>typedef enum{<br> STEP_1 = 0,<br> STEP_2,<br> STEP_3<br>} MySteps<br><br>Then you can <br>case STEP_3:<br><br>After that all you do is add steps in your enumeration and not worry about what they're numbered.
This also had the benefit of naming your cases something meaningful.
<p>I've never heard of enum, that's definitely something I'll look into.<br><br>Thank you for the suggestion!</p>
<p>The code certainly shows some signs of aspiring to being a Finite State Machine (FSM). But it needs at least one other attribute to be more than just a simple linear sequencer: The ability to change its behaviour according to external events. That means that within each state (as coded in the example) it will sit in a loop looking for one of <em>several</em> possible things, say a timeout <strong>OR</strong> an external input, then switch it's state accordingly. In the process of switching state it would typically change an output.<br><br>The moment it has to check for more than one thing (e.g. timeout) we have to eliminate &quot;blocking&quot; calls such as Delay() and use something that doesn't tie up the processor. After all, if it's in a Delay() it can't be testing an input at the same time. For the Arduino there's a tutorial on creating &quot;non-blocking&quot; delays at <a href="http://www.splatco.com/rtos_1.htm" rel="nofollow">https://www.arduino.cc/en/Tutorial/BlinkWithoutDel...</a><br><br>Once you've eliminated blocking calls such as Delay() you are well on your way to <em>multitasking</em> - having the program seemingly do several things at once. Write each FSM as a function that gets called, does its thing, and immediately exits again. String two or more of those together inside an endless loop, and you have what is known as a <a href="http://www.splatco.com/rtos_1.htm" rel="nofollow">superloop program structure</a>.<br><br>There's more detailed description of multitasking systems in a post I wrote <a href="http://www.splatco.com/rtos_1.htm" rel="nofollow">here</a>. </p>
<p>You are correct.</p><p>We've done some instructables that cover the more &quot;multitasking&quot; aspect of programming. In our &quot;<a href="https://www.instructables.com/id/Monitoring-Load-Feedback-of-an-Actuator/" rel="nofollow">Monitoring Load Feedback of an Actuator</a>&quot;, we use if statements to check if the load is over the limit, allowing us to always monitor the current as well as keep the actuator moving. We also use statements like that to debounce buttons, using millis().<br></p><p>Interrupts are very useful when trying to implement &quot;superloop&quot; codes, <br>we'll be going over more programming methods in future Instructables! In the next couple weeks we'll be releasing a multi-part series of Instructables that uses interrupts to monitor multiple inputs at the same time.<br><br>Stay tuned!</p>
<p>Very informative; I like the way you brought it all together one step at a time.</p><p>I am looking forward to viewing your other Instructables as well.</p><p>Build_it_Bob</p>
<p>Thanks for the positive feedback! Stay tuned for more. </p>
<p>Can you explain what the program gains from the Switch statements? The sequence will in any event stall (block) during the Delay() calls and the While loops that wait for external events. Why would the program not work if all the Switch/Case stuff was removed?</p>
<p>Programs can achieve the same result with many different ways of coding it.The switch statements are good for easily seeing when your program moves from state to state. This make debugging much easier, you can easily see in which state where the program gets caught up.</p><p>You are correct, it will get &quot;stuck&quot; while it is waiting for the delays and inputs, you could achieve the same result with a series of if statements and have your program continuously loop. If you are monitoring multiple things at once, you would need to program to continuously check everything, but doing a linear program like this the switch works well for basic, linear programs.<br><br>If you check our other instructable, https://www.instructables.com/id/Monitoring-Load-Feedback-of-an-Actuator/, you can see an example of a program continuously looping, so it can check the current that the actuator is pulling, as well as keeping the actuator in motion.</p>
<p>Mechanical limit<br>switches can be a costly problem. Emerson electric made gearmotors<br>for dental chairs some time ago in which limit switches were failing<br>far too early in their life cycle, and were made by the venerable<br>Micro Switch corp. using their patented snap action leaf spring. We<br>found a substitute switch that used an entirely different actuation<br>method used by another vendor, and replaced all failures, achieving a<br>100% success rate of repair. Never could get an answer from Emerson<br>or Micro about what their problem was either.</p>

About This Instructable

23,760views

306favorites

License:

Bio: Progressive Automations is your primary source for electric linear actuators, motion control systems and automation accessories. For over a decade, we have supplied various industries ... More »
More by Progressive Automations:DIY Portable Single Axis Solar Tracker Hall Effect Sensors 3: PID Control Hall Effect Sensors 2: Synchronizing Motion 
Add instructable to: