Using 'switch () { case#: do something.. Simpler method or a better alternative?

Have some code which basically makes use of the "switch....case" for dealing with a potentiometer. Problem is the sketch size is just a little too long for the Arduino, and all these 'case #:' lines are heavily contributing to that (about 106 cases, so 318 lines of code). I know there is the alternative of IF/Else statements, although unsure if they would likely reduce the code length at all
Does anyone know of a method for reducing the 318 lines of code, to something.....well more efficient?

Example below.

int vINTERVAL = map(ADJUSTpot,0, 1023, 0, 19):
switch(vINTERVAL) {
case 0:
ManOUT = 100;
ManIN = -100;
break;
case 1:
ManOUT = 50;
ManIN = -50;
break;
case 2:
ManOUT = 20;
ManIN = -20;
break;

etc., etc., etc.,

Thanks

Is there any matematical relationship between vINTERVAL and ManOUT ?

is ManOUT always -1 * ManIN ??

Just look up the result you want in an array.

Mark

This statement:

t vINTERVAL = map(ADJUSTpot,0, 1023, 0, 19):

suggests you want to take whatever value comes back from your analog read and map that value to a range of 0 to 19. How can there be 318 lines of code? If there's only 20 values and each takes 4 lines, where does the 318 come from? Don't forget that a switch expression is on an integral value, not a floating point value.

You could use something like:

int myConvert[2][20] = { {100, -100}, {50, -50}, {20, -20}, /* the rest of your values */
                            };

and then index into the array:

int vINTERVAL = map(ADJUSTpot,0, 1023, 0, 19):

   ManOut = myConvert[0][vINTERVAL ];
   ManIn = myConvert[1][vINTERVAL ];

// more code...

I know there is the alternative of IF/Else statements,

A little knowledge is a dangerous thing.

Try this

#define NPT (6)
int avals[NPT] = { 0, 200, 400, 600, 800, 1023 };
int manouts[NPT]={ 100, 50, 40, 32, 22, 19 };
int manints[NPT]={ -100, -55, -39, -27, -23, -16} ;


void loop( )
{
   int a = analogRead(A0) ;
   int MANout ;
   int MANin ;
   for ( int i=1 ; i<NPT ; i++ )
   {
      if ( a <= avals[i] )
     {
         int n1 = a-avals[i-1] ;
         int n2 = avals[i]-avals[i-1];
         MANout = manouts[i-1] + (n1*(manouts[i]-manouts[i-1]))/(n2) ;
         MANin = manins[i-1] + (n1*(manins[i]-manins[i-1]))/(n2) ;
         break ;
     }
  }
  // more stuff
}

You need to watch out for integer overflow here, it depends on the numbers in your model. The alternative is to use float.

@OP - it would be a good idea it you post the rest of your code. We may be able of educe it size by a great deal.

Mark

@rogerclark - No particular mathematical relationship between vINTERNAL and ManOUT. THe -/+ values are for manual control of a motor, depending on which direction it is moving.
@econjack - That is correct. Remapping the analog read from a potentiometer to a set of values for controlling motor speed in either direction. The 318 lines of code come from the 40 for either direction, plus there is 2 more long sets of the similar 'switch...case' use. Hence the interest in reducing it all to something more efficient. Will try the array idea.

@michinyon - gave your code suggestion a go. Although I get error
core.a(main.cpp.o): In function main': C:\\Arduino\hardware\arduino\cores\arduino/main.cpp:11: undefined reference to setup'

If remove the (6), changes to
In function 'void loop()':
error: expected primary-expression before ';' token

referring to the line

for ( int i=1 ; i<NPT ; i++ )

I'm guessing NPT isn't for calling the network time.

The array idea seems like a good way to head, but definitely the first time I've used it for something this long in this way. Will keep trying to get it working. Would of course appreciate any help.
In the meantime here's the part of the code I'm working with. Would welcome any streamlining suggestions:

void potrequest1() {
  PotChanged = 50;
  int ADJUSTpot = A1_Read;
  ADJUSTpot = ((ADJUSTpot / 10) * 10); 
  int vINTERVAL = map(ADJUSTpot, 0, 1023, 0, 19);

  
 switch (vINTERVAL) {
  case 0:    
    ManuOUT = 200;
    ManuIN = -200;
    break;
  case 1:    
    ManuOUT = 120;
    ManuIN = -120;
    break;
  case 2:
    ManuOUT = 80;
    ManuIN = -80;
    break;
  case 3:    
    ManuOUT = 40;
    ManuIN = -40;
    break;
  case 4:     
    ManuOUT = 20;
    ManuIN = -20;
    break;
  case 5:    
    ManuOUT = 10;
    ManuIN = -10;
    break;
  case 6:
    ManuOUT = 5;
    ManuIN = -5;
    break;
  case 7:    
    ManuOUT = 3;
    ManuIN = -3;
    break;
  case 8:    
    ManuOUT = 1;
    ManuIN = -1;
    break;
  case 9:    
    ManuOUT = 0;
    ManuIN = 0;
    break;
  case 10:
    ManuOUT = -1;
    ManuIN = 1;
    break;
  case 11:    
    ManuOUT = -3;
    ManuIN = 3;
    break;
  case 12:    
    ManuOUT = -5;
    ManuIN = 5;
    break;
  case 13:    
    ManuOUT = -10;
    ManuIN = 10;
    break;
  case 14:
    ManuOUT = -20;
    ManuIN = 20;
    break;
  case 15:    
    ManuOUT = -40;
    ManuIN = 40;
    break;
  case 16:    
    ManuOUT = -80;
    ManuIN = 80;
    break;
  case 17:
    ManuOUT = -120;
    ManuIN = 120;
    break;   
  case 18:
    ManuOUT = -200;
    ManuIN = 200;
    break;    

  }
  if (ManuDIR == 100){
    displaydigits(ManuOUT);
  }
  if (ManuDIR == 50){
    displaydigits(ManuIN);
  }
}


void potrequest2(int frog) {
  PotChanged = 50;
  int ADJUSTpot = A1_Read;
  int vINTERVAL = map(ADJUSTpot, 0, 1010, 0, frog);
  switch (vINTERVAL) {
  case 0:    
    pot2 = 30;
    INTERVAL = 1;
    break;
  case 1:  
    pot2 = 60,
    INTERVAL = 2;
    break;
  case 2:
    pot2 = 90;
    INTERVAL = 3;    
    break;
  case 3: 
    pot2 = 120;
    INTERVAL = 4;   
    break;    
  case 4:
    pot2 = 150;
    INTERVAL = 5;   
    break;  
  case 5: 
    pot2 = 180;
    INTERVAL = 6;   
    break;  
  case 6: 
    pot2 = 210;
    INTERVAL = 7;   
    break;  
  case 7: 
    pot2 = 240;
    INTERVAL = 8;   
    break;  
  case 8: 
    pot2 = 270;
    INTERVAL = 9;   
    break;  
  case 9: 
    pot2 = 300;
    INTERVAL = 10;   
    break;  
  case 10: 
    //   pot1 = 10;
    pot2 = 330;
    INTERVAL = 11;   
    break;  
  case 11: 
    //   pot1 = 11;
    pot2 = 360;
    INTERVAL = 12;   
    break;  
  case 12: 
    //    pot1 = 12;
    pot2 = 390;
    INTERVAL = 13;   
    break;  
  case 13: 
    //    pot1 = 13;
    pot2 = 420;
    INTERVAL = 14;   
    break;  
////////////////////////////////Took out a bunch of similar code here so it would post     /////////////////////////////////         

  }
}

/*void SETX(){
 BUTTON = 0;
 Serial1.print("SETX");
 delay_ms(500);
 PROG++;
 }
 */

void SET(){
  CLEARDISP();
  Serial1.print("xSET");
  BUTTON = 0;
  delay(300); 
}


int quickwrite(long value, int LOC1, int LOC2) {
  int stuff = A0_Read;
  long timer = 1;
  while((stuff >= 970) && (stuff <= 990)) {
    timer++;
    if (timer > 30000){
      SETXwrite(LOC1, value/256);
      SETXwrite(LOC2, value%256);
      Serial1.print("xxxx");
      delay(250);
      Serial1.print("xSET");
      // Serial1.println(value);
    }
    stuff = analogRead(A0);
    if (stuff == 0){
      break; 
    }
  } 
}

void buttonout(){
  BUTTON = 0;
  delay(150);
}

Read about arrays
http://www.thebox.myzen.co.uk/Tutorial/Arrays.html

Then just define two arrays ManuOUTVal and ManuINVal that contain the values and the whole of your case statement reduces to just two lines:-

ManuOUT = ManuOUTVal[vINTERVAL];
ManuIN = ManuINVal[vINTERVAL];

potrequest2 can be done with just a simple claculation.

Something like

pot2 = (1+vINTERVAL)*30;
INTERVAL = vINTERVAL+1;

Mark

Thanks for the link Mike. I'll have a read through.
Having some trouble with using ManOUTVal and ManINVal, error is saying

ManuOUTval' cannot be used as a function

Will look at changing the code when I get home in an couple of hours.
add in the potrequest2 bit.

Ok Tried to work through the array idea. Code below. Compiles with 4,262 bytes. Haven't included it the main code yet, because it requires a lot of changes to it, and I wan't to make sure I've got the array working first.

To define the task:
I want to it to read the potentiometer,
Remap those values (0-1023), to a series of cases (0-19), which are in the array 'avals'
Then depending on what value comes back after smoothing using the (ADJUSTpot/10) *10 look for which case this is in and set the values of Out and In to a series of numbers, which are now included in the array 'manouts' and 'manints'.
In the second 'potrequest2', I plan to have it set values, previously set manually, from 10-9999, with bigger increments as the number goes higher (those numbers are commented out at the bottom for the moment).

I'm not sure if this code is doing this, appreciate if anyone can point out my mistake or the many mistakes.

#define NOS (19)
int main(){} 
uint8_t PotChanged;
uint8_t ManuDIR;
int avals[NOS] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18};   /////////// Case Arrays
int manouts[NOS] = {200, 120, 80, 40, 20, 10, 5, 3, 1, 0, -1, -3, -5, -10, -20, -40, -80, -120, -200};  /////////////Values for MANout
int manints[NOS] = {-200, -120, -80, -40, -20, -10, -5, -3, -1, 0, 1, 3, 5, 10, 20, 40, 80, 120, 200};   /////////////Values for MANin

void potrequest1()
{
//  int a = analogRead(A0);
  int ADJUSTpot = analogRead(A0);
  ADJUSTpot = ((ADJUSTpot/10)*10);
  int vINTERVAL = map(ADJUSTpot, 0, 1023, 0, 19);
  int MANout;
  int MANin;
  for (int i=1; i<NOS; i++)
  {
    if (ADJUSTpot <= avals[i])
    {
      int n1 = ADJUSTpot-avals[i-1];
      int n2 = avals[i]-avals[i-1];
      MANout = manouts[i-1] + (n1*(manouts[i]-manouts[i-1]))/(n2);
      MANin = manints[i-1] + (n1*(manints[i]-manints[i-1]))/(n2);
      break;
    }
  }
}

//if (ManuDir==100){
//  displaydigits(ManuOUT);
//}

#define INT (86400)
void potrequest2(){
  int pot2;
  int vINTERVAL;
  int INTERVAL;
pot2 = (1+vINTERVAL)*30;
INTERVAL = vINTERVAL+1;

}  
#
void potrequest3(int dog){
  int pot3;
//  int a = analogRead(A0);
  int ADJUSTpot = analogRead(A0);
  int vINTERVAL;
  int INTERVAL;
pot3 = (1+vINTERVAL)*10;
INTERVAL = vINTERVAL+1;
}
//  int INTERVAL[] = {1, 2, 3, 4, 5, 6,7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
//20, 25,30, 35, 40, 45, 50, 55, 60, 75, 90, 105, 120, 135, 150, 165, 180, 195, 210, 225, 240, 255, 260, 275, 300,
//330, 360, 390, 420, 450, 480, 510, 540, 570, 600, 660, 720, 780, 840, 900, 960, 1020, 1080, 1140, 1200, 1260, 1320, 
//1380, 1440, 1500, 1560, 1620, 1680,1740, 1800, 2100, 2400, 3000, 3600, 5400, 7200, 9000, 10800, 12600, 14400, 18000, 
//21600, 28800, 43200, 86400};

Thanks for the help in advance.

You use :-

#define INT (86400)

Why the brackets. The pre compiler will change every occurrence of INT into (86400) surely you just want the number 86400.

#define INT 86400

You use:-

  int vINTERVAL;
  int INTERVAL;
pot3 = (1+vINTERVAL)*10;
INTERVAL = vINTERVAL+1;

You do not define a value to vINTERVAL so how do you expect the last line to work?

ManuOUTval' cannot be used as a function

You might be seeing this message because your are using parentheses with ManuOUTval rather than brackets. That is, you are using:

  temp = ManuOUTval(x);      // WRONG: parentheses

when actually you mean:

  temp = ManuOUTval[x];      // RIGHT: brackets

86400 are number of seconds in 24 hours. Which would represent the total Interval range between events.
I may have been habitually under the impression that the brackets were necessary for defining this many seconds in the interval array. Not sure now which way should go?
I see though what your saying Mike. I had the array originally with all these interval values commented out at the bottom of the code. Previously it read

#define INT (85)
void potrequest2(){
  int pot2;
  int vINTERVAL;
///////// Array was continuous single line, Not per line as shown below.
int INTERVAL[INT] = {1, 2, 3, 4, 5, 6,7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 
20, 25,30, 35, 40, 45, 50, 55, 60, 75, 90, 105, 120, 135, 150, 165, 180, 195, 210, 225, 240, 255, 260, 275, 300,
330, 360, 390, 420, 450, 480, 510, 540, 570, 600, 660, 720, 780, 840, 900, 960, 1020, 1080, 1140, 1200, 1260, 1320, 
1380, 1440, 1500, 1560, 1620, 1680,1740, 1800, 2100, 2400, 3000, 3600, 5400, 7200, 9000, 10800, 12600, 14400, 18000, 
21600, 28800, 43200, 86400};
pot2 = (1+vINTERVAL)*30;
INTERVAL = vINTERVAL+1;

}

Since the numbers are not always consecutive though, thinking 86400 intervals might be above the sensitivity of the pots to adjust easily.

Thanks for the keen eye Econjack.
I was typing the code on a small screen, and a non-standard keyboard for me.
Will run through it again.

The second is linear, and the equation is above

The first one,
One value is -1 * the other value, so you only have to "get" one value
The values are a parabola
aX^2 + bX + c = 0
There is an equation to solve this, if you google quadratic equation you can find the "simple" solution.

So, there is a simple one-liner (actually 2-liner because there are 2 results, and you have to select one)