Pages: [1] 2   Go Down
Author Topic: Switch / Case with multiple variables?  (Read 4490 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 23
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ive been playing with switch / case and was wondering if there is a way to use multiple variables
something like

switch (a, b c)
{
    case 1, 2, 3:
    //do something
    return;
}

i know that code wont compile, but is there a proper syntax for something like that or is there a different tool?
Logged

UK
Offline Offline
Faraday Member
**
Karma: 100
Posts: 4153
Where is your SSCCE?!?!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

You cannot do that with case.  You will have to use if / else if etc.
Logged

Get 10% off all 4D Systems TFT screens this month: use discount code MAJENKO10

Offline Offline
Newbie
*
Karma: 0
Posts: 23
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

too bad there isnt something like switch / case for multiple variables, that would be slick
Logged

UK
Offline Offline
Faraday Member
**
Karma: 100
Posts: 4153
Where is your SSCCE?!?!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

It would, but alas not.
Logged

Get 10% off all 4D Systems TFT screens this month: use discount code MAJENKO10

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 309
Posts: 26495
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

If you tell us what it is you're trying to do, we could maybe suggest a solution.
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Offline Offline
Newbie
*
Karma: 0
Posts: 23
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

im trying to program a wall avoiding robot,  it has a ping)) sensor on a servo that gets distances from the left right and center then decides what to do.  if it sees something on the left side it will turn right even if it should back up or something because this comes first in the code.  I would like to write something that considers all the input before deciding but dont know what tool to use or how to format it with if, else if statements

here is my current main loop, i think most of the function names are pretty self explanitory
Code:
void loop()
{
  directionalPing();
  if(pingLeft <= 6)
    {
      turnRight(600);
      return;
    }
  if(pingRight <= 6)
    {
      turnLeft(600);
      return;
    }
  if(pingForward <= 6)
    {
      reverse(200);
      turnLeft(600);
      return;
    }
  if(pingForward > 6)
    {
      forward(500);
      reverse(50);
      return;
    }
}
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 223
Posts: 13870
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Ive been playing with switch / case and was wondering if there is a way to use multiple variables
something like

switch (a, b c)
{
    case 1, 2, 3:
    //do something
    return;
}

i know that code wont compile, but is there a proper syntax for something like that or is there a different tool?

1) you can nest switches

switch (a, b c)
{
    case 1:
    switch(b)
    {
       case 2:
 etc

will result is a forest of code.

2) combine abc to one state (bit stuffing)

depending on the range of the values a,b,c you can pack these three vars in one .
suppose a = 0-3 (needs 2 bits)  and b = 0-31 (5 bits) and c = 0-8, (3 bits)
then you can make

int val = a + b << 2 + c << 7   // val = [0000 00CC CBBB BBAA]  bit pattern

and do  the same for all relevant values.
As this is quite error prone you can "macrofy" this, see the sample sketch below (IDE 0.22)

Code:
//
//    FILE: MultiSwitch.pde
//  AUTHOR: Rob Tillaart
//    DATE: 09-06-2012
//
// PUPROSE: macrofying a multiple switch
//

#define SWITCH(a,b,c) switch(a + b<<2 + c<<7)
#define CASE(a,b,c) case(a + b<<2 + c<<7)

void setup()
{
  Serial.begin(9600);
  Serial.println("start...");
}

void loop()
{
  int a=2, b=3, c=4;
  int x = 5;

  SWITCH(a,b,c)
  {
    CASE(1,2,3):
    x=4;
    break;
    CASE(2,3,4):
    x=3;
    break;
  default:
    x=6;
    break;
  }
  Serial.println(x);
  delay(500);

  a=1, b=2, c=3;

  SWITCH(a,b,c)
  {
    CASE(1,2,3):
    x=4;
    break;
    CASE(2,3,4):
    x=3;
    break;
  default:
    x=6;
    break;
  }
  Serial.println(x);
  delay(500);
  
  a++;
  
  SWITCH(a,b,c)
  {
    CASE(1,2,3):
    x=4;
    break;
    CASE(2,3,4):
    x=3;
    break;
  default:
    x=6;
    break;
  }
  Serial.println(x);
  delay(500);
}

notes:
- all warnings about using macros apply,
- there are limitations how long the bitpattern can be => use a long for var a to maximise the trick.
- multiple multicase switches need additional macros

« Last Edit: June 09, 2012, 01:45:36 am by robtillaart » Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 223
Posts: 13870
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


append.

instead of a macro one could think of using a function, but that doesn't work as the case is expecting a const value compile time. However one could do with just one macro mimicing the function. (coffee really clears up the mind smiley-wink

So here is the code with a normal switch and only one macro
Code:
//
//    FILE: MultiSwitch.pde
//  AUTHOR: Rob Tillaart
//    DATE: 09-06-2012
//
// PUPROSE: macrofying a multiple switch
//

#define H(a,b,c) (a + b<<2 + c<<7)

void setup()
{
  Serial.begin(9600);
  Serial.println("start...");
}

void loop()
{
  int a=2, b=3, c=4;
  int x = 5;

  switch(H(a,b,c))
  {
    case(H(1,2,3)):
    x=4;
    break;
    case(H(2,3,4)):
    x=3;
    break;
  default:
    x=6;
    break;
  }
  Serial.println(x);
  delay(500);

  a=1, b=2, c=3;

  switch(H(a,b,c))
  {
    case(H(1,2,3)):
    x=4;
    break;
    case(H(2,3,4)):
    x=3;
    break;
  default:
    x=6;
    break;
  }
  Serial.println(x);
  delay(500);

 
  a++;
 
  switch(H(a,b,c))
  {
    case(H(1,2,3)):
    x=4;
    break;
    case(H(2,3,4)):
    x=3;
    break;
  default:
    x=6;
    break;
  }
  Serial.println(x);
  delay(500);

}



Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Offline Offline
Newbie
*
Karma: 0
Posts: 23
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thank you robtillaart,  Im working on using that technique in my code now. 
Logged

New Jersey
Offline Offline
Faraday Member
**
Karma: 70
Posts: 3732
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I would like to write something that considers all the input before deciding but dont know what tool to use or how to format it with if, else if statements

I know I pointed you down this road, but what's the requirement here? Once you have all the various ping measures, what's your algorithm for deciding how to move?
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 23
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I don't quite know how to go about developing an algorithm for the movement (im still pretty new at programming anything).  I would like to start with something like if pingLeft pingRight and pingForward all revieve <6 then it backs up until it registers a longer distance on one of the sides and then turns that way.

but on a more general programming question:
what are various ways people use to imagine and or visualize different algorithms?
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 23
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

so this is kinda what i had in mind for the possible decisions - indicates a reading greater than 12"  + indicates a reading of either 6 or between 6 and 12 depending on situation  but im still not quite sure how to implement it into code that checks all 3 reading before making a decision

1) L-  F-  R+  |  x<6: hard turn left
                   |  6> x >12 gentle turn left

2) L- F+ R-    |  reverse measure again turn towards greatest distance

3) L+ F- R=   |  y<6: hard turn right
                   |  6> y >12 gentle turn right

4) L- F+ R+   |  hard turn left

5) L+ F+ R-   |  hard turn right

6) L+ F+ R+  |  reverse, check L & R turn towards greater distance

7) L+ F- R+   |  if distance between objects is greater than width of robot continue forward
                   |  if distance between objects is smaller than robot reverse and turn towards
                   |  greatest reading



EDIT:  does anyone know of somewhere i could go on them tharr interwebs to learn about such a thing? (somewhere or something free)
« Last Edit: June 10, 2012, 12:05:28 am by ffmurray » Logged

UK
Offline Offline
Shannon Member
****
Karma: 223
Posts: 12630
-
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

What you're trying to do would make sense if you were trying to create a compound finite state machine - although there are better ways to do it.

But it seems to me that is not what you need here. As I see it, you have a couple of algorithms to decide what action to take, and there is some precedence between them. If there is a wall in front then back up; otherwise if there is an obstruction to the left then steer right, and so on.

In that case I'd suggest using simple if/else style logic to decide what action to take and then have a separate chunk of code that carries it out. If there are lots of actions you might find it convenient to define them as enumerated values and then use a switch statement to execute the chosen action.
Logged

I only provide help via the forum - please do not contact me for private consultancy.

Offline Offline
Newbie
*
Karma: 0
Posts: 23
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
What you're trying to do would make sense if you were trying to create a compound finite state machine - although there are better ways to do it.
what sort of better ways?  I dont really care so much about building the robot, but learning to program in general, the tools of problem solving used to write code.
Logged

Prague
Offline Offline
Jr. Member
**
Karma: 0
Posts: 51
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


when I recieve UDP command, I use switch in following way to join several possibilities to one result:

Code:
    if(packetBuffer[0] == 'R' || packetBuffer[0] == 'r') switch_value = 0; //reset
    if(packetBuffer[0] == 'W' || packetBuffer[0] == 'w') switch_value = 1; //speed up
    if(packetBuffer[0] == 'S' || packetBuffer[0] == 's') switch_value = 2; //speed down

    switch (switch_value) {
    case 0:
      servoPos = 90;           // tell servo to go to position servoPos
      servoMove(servoPos);
      led_blink();
      break;
    case 1:
      if( servoPos >= 10 && servoPos <= 165) {
      servoPos = servoPos+5;           // tell servo to go to position servoPos
      servoMove(servoPos);
      }
      led_blink();
      break;
    case 2:
      if( servoPos >= 15 && servoPos <= 165) {
      servoPos = servoPos-5;           // tell servo to go to position servoPos
      servoMove(servoPos);
      }
      led_blink();
      break;
    default:
      // if nothing else matches, do the default
      // default is optional
Logged

Pages: [1] 2   Go Up
Jump to: