Case Structures

Hello,

I'm an educator/grad student working on developing curriculum for data acquisition and control using Arduino Uno. I am attempting to create a similar curriculum to some that has already been developed for use with a National Instruments device using LabView. I am quite new to Arduino and C/C++, so forgive my extensive ignorance.

My question is how to use case structures with Arduino. Specifically, I want to use two switches as inputs to control a traffic signal sequence. For example, if Switch 1 is High and Switch 2 is Low, Sequence A happens (case structure). If Switch 1 is High and Switch 2 is High, Sequence B happens. If Switch 1 is Low and Switch 2 is High, Sequence C happens, and so on for all possible combinations of the two switches. I think the most logical way to do this appears to be the switch case function.

In LabView, this is done using a DAQ Assistant for the inputs, which goes to an index array which then goes to a case structure with a separate case for each condition. I'm just not quite sure how this all translates to Arduino, whether I even need the array at all or how to properly define it, etc. I've read Arduino's documentation on the switch case command, arrays, etc, but I just can't quite put it all together. I do know I could do this using a rather convoluted series of if/else functions, but I want to teach the best/most efficient way to do this as equivalently as is reasonable to the LabView method just described.

Any help in getting me started would be much appreciated.

If anyone knows LabView, I've attached a diagram of what I'm attempting to do in Arduino below.

labview.png

HINT #1: You can force this into a switch...case structure with Arduino, but because switches are either HIGH or LOW (two cases), an if...else structure makes more sense to me.

HINT #2: It would be wise to learn about Finite State Machines (FSM).

Good Luck!

Maybe this is what you're looking for:
Define sequenceA, sequenceB, sequenceC, sequenceD as data structures.
Place the data structures in an array:

sequences[2][2] = { {sequenceA, sequenceB}, {sequenceC, sequenceD} };
switch0 = 1; //high
switch1 = 0; //low
n = 3; //fourth element in a sequence
nextTrafficSignal = sequences[switch0][switch1].sequence[n];

Details depend on how the sequences will be defined. e.g.
Does each sequence have the same number of elements?
Are the sequence elements homogeneous?

Thanks, all!

I think Delta_G's response makes the most sense as far as what concepts I'm trying to teach, so I'll try that route first. I know using the switch...case might be overkill for only two switches, but I'm also trying to teach concepts in addition to just getting it to work. So I'll give that a try, but the other answers look like good routes to go as well, so thank you all for your responses. I'll report back on my solution or if I have any follow-up questions.

Thank you!

If anyone else has additional insight, feel free to continue commenting.

The best way to illustrate a switch/case is to create a state-machine.

Two concepts with one stone!

Ok, so here's what I've got so far. The obvious problem here is that I'm going to get an error that "a function-definition is not allowed here before '{' token. I'm still very early on the syntax learning curve, so I know there's something wrong, but I don't know how to fix it.

But at any rate, is this a workable way to go?

Two people have suggested state machines, so I'm going to go read up on how to do that, but in the meantime I'd be grateful for some feedback on what I've got here so far.

int green = 2;
int yellow = 3;
int red = 4;
int switch0 = 8;
int switch1 = 9;

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

  pinMode(green, OUTPUT);
  pinMode(yellow, OUTPUT);
  pinMode(red, OUTPUT);
  pinMode(switch0, INPUT);
  pinMode(switch1, INPUT);
  
}

void loop() {
  // put your main code here, to run repeatedly:
  
  
 //create a new variable which returns a 1 or a 0 based on
 //whether switch0 is high or low

  int checkSwitch0(){
    if(digitalRead(switch0 = HIGH) {
      return 1;
      else{
        return 0;
      }
    }
  }
  
  //create a new variable which returns a 2 or a 0 based on
  //whether switch1 is high or low

  int checkSwitch1(){
    if(digitalRead(switch1 = HIGH) {
      return 2;
      else{
        return 0;
      }
    }
  }

  //add the two variables to get a number from 0 to 3
  //where the number tells what configuration the switches are in

  int SwitchCondition = checkSwitch0 + checkSwitch1;
  

  //program executes a case depending on the value of SwitchCondition

  switch (SwitchCondition){
    case 0:

      //both switches are LOW
      //all lamps off

      digitalWrite(green, LOW);
      digitalWrite(yellow, LOW);
      digitalWrite(red, LOW);
      
    case 1:

      //switch0 is HIGH, switch1 is LOW
      //turn on green for 3000
      //turn on yellow for 1000
      //turn on red for 4000

      digitalWrite(green, HIGH);
      delay(3000);
      digitalWrite(green, LOW);
      
      digitalWrite(yellow, HIGH);
      delay(1000);
      digitalWrite(yellow, LOW);
      
      digitalWrite(red, HIGH);
      delay(4000); 
      digitalWrite(red, LOW);
 
   case 2:

      //switch0 is LOW, switch1 is HIGH
      //turn on red for 1000
      //turn off all for 1000

      digitalWrite(red, HIGH);
      delay(1000);
      digitalWrite(red, LOW);
      delay(1000);
   
   case 3:

      //both switches high
      //turn on yellow for 1000
      //turn off all for 1000

      digitalWrite(yellow, HIGH);
      delay(1000);
      digitalWrite(yellow, LOW);
      delay(1000);

   default:

       //all lamps off

       digitalWrite(red, LOW);
       digitalWrite(yellow, LOW);
       digitalWrite(green, LOW);
  }
}

Errors:

Arduino: 1.6.0 (Windows 7), Board: "Arduino Uno"

sketch_mar11a.ino: In function 'void loop()':
sketch_mar11a.ino:24:21: error: a function-definition is not allowed here before '{' token
sketch_mar11a.ino:93:1: error: expected '}' at end of input
Error compiling.

  int checkSwitch0(){

You can't embed one function inside another.

You're defining checkswitch() functions inside of another function. That's not legal C. Put function definitions outside of other function definitions.

You're then accessing these functions as if they were variables. That's not legal C.

  int checkSwitch0(){
    if(digitalRead(switch0 = HIGH) {
      return 1;
      else{
        return 0;
      }
    }
  }
  
  //create a new function which returns a 2 or a 0 based on
  //whether switch1 is high or low

  int checkSwitch1(){
    if(digitalRead(switch1 = HIGH) {
      return 2;
      else{
        return 0;
      }
    }
  }

void loop() {
  // put your main code here, to run repeatedly:
  
  
 //create a new variable which returns a 1 or a 0 based on
 //whether switch0 is high or low



  //call the two functions and add the result to get a number from 0 to 3
  //where the number tells what configuration the switches are in

  int SwitchCondition = checkSwitch0() + checkSwitch1();

Or you could just do...

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


  //read the switches and multiply second one by 2 - digitalRead() returns
  //an integer; HIGH and LOW are just #defines equal to 1 and 0.

  int SwitchCondition = digitalRead(switch0) + digitalRead(switch1)*2; 
  //or (digitalRead(switch1)<<1), which may be a better way to think about it. I always

You're then accessing these functions as if they were variables. That's not legal C

?

Ha! No kidding, that would be much easier. Thanks!

Another thing - thisif(digitalRead(switch1 = HIGH) {will compile, but won't do what you expect, and is another really good reason to qualify pin numbers with "const".

Ok, thanks everyone.

So, I qualified all my pin numbers with "const", then removed the offending function definitions and replaced the whole thing with SwitchCondition = digitalRead(switch0) + (digitalRead(switch1)*2). Compiled and uploaded, and the device works but is not outputting the correct sequences on the traffic light. My guess is that you can't add or multiply HIGHs and LOWs...or can you? I imagine I need to convert the HIGH and LOW readings to 1s or 0s, but where should I put that, since I can't define a function inside my loop?

Here's what I have now, for reference:

const int green = 2;
const int yellow = 3;
const int red = 4;
const int switch0 = 8;
const int switch1 = 9;



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

  pinMode(green, OUTPUT);
  pinMode(yellow, OUTPUT);
  pinMode(red, OUTPUT);
  pinMode(switch0, INPUT);
  pinMode(switch1, INPUT);
  
}

void loop() {
  // put your main code here, to run repeatedly:
  
  //define a variable which adds the values of the input pins to get a number from 0-3
  
  int SwitchCondition = digitalRead(switch0) + (digitalRead(switch1)*2);
  
  //program executes a case depending on the value of SwitchCondition

  switch (SwitchCondition){
    case 0:
    
      //both switches are LOW
      //all lamps off
      
      digitalWrite(green, LOW);
      digitalWrite(yellow, LOW);
      digitalWrite(red, LOW);
      
    case 1:
    
      //switch0 is HIGH, switch1 is LOW
      //turn on green for 3000
      //turn on yellow for 1000
      //turn on red for 4000
      
      digitalWrite(green, HIGH);
      delay(3000);
      digitalWrite(green, LOW);
      
      digitalWrite(yellow, HIGH);
      delay(1000);
      digitalWrite(yellow, LOW);
      
      digitalWrite(red, HIGH);
      delay(4000); 
      digitalWrite(red, LOW);
 
   case 2:
   
      //switch0 is LOW, switch1 is HIGH
      //turn on red for 1000
      //turn off all for 1000
      
      digitalWrite(red, HIGH);
      delay(1000);
      digitalWrite(red, LOW);
      delay(1000);
   
   case 3:
   
      //both switches high
      //turn on yellow for 1000
      //turn off all for 1000
      
      digitalWrite(yellow, HIGH);
      delay(1000);
      digitalWrite(yellow, LOW);
      delay(1000);
      
   default:
   
       //all lamps off
       
       digitalWrite(red, LOW);
       digitalWrite(yellow, LOW);
       digitalWrite(green, LOW);
  }
}

I imagine I need to convert the HIGH and LOW readings to 1s or 0s

HIGH is defined to be 1, LOW is defined to be 0.

"case"s need "break"s to prevent fall through.

Ah, nice catch!

Works perfectly! Thanks so much for your help!

Now to go learn about this state machine...

Cheers, all!