Go Down

Topic: Case switch instead of if statement (Read 852 times) previous topic - next topic

hun1

Hi again everyone! I'm think of using multiple pushbuttons for a stepper motor project.  I'm thinking like 5 or 6 pushbuttons to tell the stepper motor to go to specified place.  Anyway, i'm wondering if the case switch is better to use then a series of if/then statements for this project.  Also, i'm confused with the case switch in regards to using pushbuttons.  Does anyone know any good tutorials for this besides the provided arduino tutorial on the website? thanks! :)

johnwasser

The switch/case statement is used when you are comparing an integer value against a number of integer constants:

If your code looks something like this:
Code: [Select]

int x = f();

if (x == 1)
   do the stuff for 1;
else
if (x == 2)
   do the stuff for 2;
else
if (x == 5)
   do the stuff for 5;
else
if (x == 17)
   do the stuff for 17;


you can re-write it to be this:

Code: [Select]

int x = f();
switch (x)
    {
case 1:
   do the stuff for 1;
   break;
case 2:
   do the stuff for 2;
   break;
case 5:
   do the stuff for 5;
   break;
case 17:
   do the stuff for 17;
   break;
   }
Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

liudr

I don't think you should use switch-case for what you intend to do. A switch-case is used when the input has multiple values but your button can yield only on and off. Just use if statement will do. If you want some efficiency, you can use array to store pins that are connected to buttons and distances that each button represents.

hun1

So I just bought the Rugged Motor Driver for the Arduino and it's cool! In my code I have an if within an if statement and it wont work right.  I want to push a button and have the motor move back to a limiter switch to calibrate itself and then move forward.  But Im just not getting it.  Any suggestions guys?

Code: [Select]



#include <Button.h>
#include <Stepper.h>

#define STEPS_PER_REVOLUTION 200

// Pick correct Arduino development board for Rugged Motor Driver
#define BOARD  0   /* Arduino Duemilanove/Uno (ATmega328P) */
//#define BOARD  1   /* Arduino Mega (ATmega1280) */
//#define BOARD  2   /* Rugged Circuits Gator (ATmega324P) */

#ifndef BOARD
#  if defined(__AVR_ATmega328P__)
#    define BOARD 0
#  elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
#    define BOARD 1
#  elif defined(__AVR_ATmega324P__)
#    define BOARD 2
#  else
#    error You must define BOARD near the top of this file
#  endif
#endif

#if (BOARD!=0) && (BOARD!=1) && (BOARD!=2)
#error Unknown board
#endif


// Enable (PWM) outputs
#define EN1_PIN 3
#define EN2_PIN 11

// Direction outputs
#define DIR1_PIN 12
#define DIR2_PIN 13

// Fault inputs, active low
#define FAULT1_PIN 5
#define FAULT2_PIN 8

Stepper stepper(STEPS_PER_REVOLUTION, DIR1_PIN, DIR2_PIN);

// Set initial default values
unsigned RPM = 50;
unsigned PWM = 10;
unsigned DIR = -1;






//create a Button object at pin X
/*
|| Wiring:
|| GND -----/ ------ pin X
*/
Button button = Button(6,PULLUP);
Button limitsw = Button(7,PULLUP);

void setup(){
 
    // Configure all outputs off for now
  pinMode(EN1_PIN, OUTPUT); digitalWrite(EN1_PIN, LOW);
  pinMode(EN2_PIN, OUTPUT); digitalWrite(EN2_PIN, LOW);
  pinMode(DIR1_PIN, OUTPUT); digitalWrite(DIR1_PIN, LOW);
  pinMode(DIR2_PIN, OUTPUT); digitalWrite(DIR2_PIN, LOW);
 
    // Configure fault inputs with pullups
  pinMode(FAULT1_PIN, INPUT); digitalWrite(FAULT1_PIN, HIGH);
  pinMode(FAULT2_PIN, INPUT); digitalWrite(FAULT2_PIN, HIGH);
 
    Serial.begin(9600); // only necessary for debugging

  // Change from divide-by-64 prescale on Timer 2 to divide by 8 to get
  // 8-times faster PWM frequency (976 Hz --> 7.8 kHz). This should prevent
  // overcurrent conditions for steppers with high voltages and low inductance.
  TCCR2B = _BV(CS21);
}

void loop(){

 
//////////// configure button 1 /////////////

  if(button.uniquePress()){
   
  // Now enable PWM and start motion
  analogWrite(EN1_PIN, PWM);
  analogWrite(EN2_PIN, PWM);
  stepper.setSpeed(RPM);
  Serial.println("reverse");
 
 
///////// limit switch for button //////////////
    if (limitsw.uniquePress() && button.wasPressed()){
       
    analogWrite(EN1_PIN, PWM);
    analogWrite(EN2_PIN, PWM);
    stepper.setSpeed(RPM);
    Serial.println("forward");
 
    // # of steps forward//
    stepper.step(600);
 
    // turn off power to the motor //
    digitalWrite(EN1_PIN, LOW);
    digitalWrite(EN2_PIN, LOW);
      }
   }
   // This is a busy-wait loop until the inter-step time passes
   stepper.step(DIR); 

}

AWOL

Quote
I want to push a button and have the motor move back to a limiter switch to calibrate itself and then move forward.  But Im just not getting it

No, we're not getting it either.
You've not described what you observed happening.
"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.

hun1

when i press button the motor turns in reverse which is what i want. I then want it to hit the limiter switch and then move a specified # of steps.  But I have to press both the button and limiter switch at the same time to make the motor move to the specified location.

Basically im trying to have 6 separate buttons move the motor in reverse till it hits the limiter switch then moves to a specified location based on the initial button they pressed. The moving in reverse and hitting the limiter is for calibration. 

My idea is:

- If i push button1 - button6 motor moves backwards. 
- When it hits limiter switch move specified # of steps depending which button was pressed.

Is this possible?

wildbill


But I have to press both the button and limiter switch at the same time to make the motor move to the specified location.


That is because your if test for the limit switch is inside the if condition for the button, i.e. it only tests the limit switch if the button is pressed. Separate the ifs & you should be good to go.

hun1

So now i've attempted to play with button state to have the program remember what button was pushed when it hits the limiter switch.  unfortunately it's not working though.

if i press button1 and then the limiter switch, it works as expected.

if i press button2 and then the limiter switch, it runs the buttonstate1 && limitsw instead of the buttonstate2 && limitsw if statement.

also, if i press the limiter switch just by itself, it goes through limiter switch && button 1 if statement and moves 600 steps regardless if I pressed button1 or not. 




Code: [Select]


#include <Button.h>
#include <Stepper.h>

#define STEPS_PER_REVOLUTION 200

// Pick correct Arduino development board for Rugged Motor Driver
#define BOARD  0   /* Arduino Duemilanove/Uno (ATmega328P) */
//#define BOARD  1   /* Arduino Mega (ATmega1280) */
//#define BOARD  2   /* Rugged Circuits Gator (ATmega324P) */

#ifndef BOARD
#  if defined(__AVR_ATmega328P__)
#    define BOARD 0
#  elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
#    define BOARD 1
#  elif defined(__AVR_ATmega324P__)
#    define BOARD 2
#  else
#    error You must define BOARD near the top of this file
#  endif
#endif

#if (BOARD!=0) && (BOARD!=1) && (BOARD!=2)
#error Unknown board
#endif


// Enable (PWM) outputs
#define EN1_PIN 3
#define EN2_PIN 11

// Direction outputs
#define DIR1_PIN 12
#define DIR2_PIN 13

// Fault inputs, active low
#define FAULT1_PIN 5
#define FAULT2_PIN 8

Stepper stepper(STEPS_PER_REVOLUTION, DIR1_PIN, DIR2_PIN);

// Set initial default values
unsigned RPM = 100;
unsigned PWM = 15;
unsigned DIR = -1;






//create a Button object at pin X
/*
|| Wiring:
|| GND -----/ ------ pin X
*/
Button button = Button(6,PULLUP);
Button button2 = Button(7,PULLUP);
Button limitsw = Button(9,PULLUP);


// try to use button state to remember which buttons was pressed //
int buttonState1 = 0;
int buttonState2 = 0;


void setup(){

    // Configure all outputs off for now
  pinMode(EN1_PIN, OUTPUT); digitalWrite(EN1_PIN, LOW);
  pinMode(EN2_PIN, OUTPUT); digitalWrite(EN2_PIN, LOW);
  pinMode(DIR1_PIN, OUTPUT); digitalWrite(DIR1_PIN, LOW);
  pinMode(DIR2_PIN, OUTPUT); digitalWrite(DIR2_PIN, LOW);

    // Configure fault inputs with pullups
  pinMode(FAULT1_PIN, INPUT); digitalWrite(FAULT1_PIN, HIGH);
  pinMode(FAULT2_PIN, INPUT); digitalWrite(FAULT2_PIN, HIGH);

    Serial.begin(9600); // only necessary for debugging

  // Change from divide-by-64 prescale on Timer 2 to divide by 8 to get
  // 8-times faster PWM frequency (976 Hz --> 7.8 kHz). This should prevent
  // overcurrent conditions for steppers with high voltages and low inductance.
  TCCR2B = _BV(CS21);


}

void loop(){


//////////// configure button 1 /////////////

  if(button.uniquePress()){
   
  // Now enable PWM and start motion
  buttonState1 = 1;
  analogWrite(EN1_PIN, PWM);
  analogWrite(EN2_PIN, PWM);
  stepper.setSpeed(RPM);
  Serial.println("reverse");
  }



///////// configure button 2//////////////

  if(button2.uniquePress()){
   
  // Now enable PWM and start motion
  buttonState2 = 1;
  analogWrite(EN1_PIN, PWM);
  analogWrite(EN2_PIN, PWM);
  stepper.setSpeed(RPM);
  Serial.println("reverse");
  }
 
//// limiter switch with button1 //
  if(buttonState1 = 1 && limitsw.uniquePress()){
    analogWrite(EN1_PIN, PWM);
    analogWrite(EN2_PIN, PWM);
    stepper.setSpeed(RPM);
    Serial.println("stop button1 reverse");
    delay(100);

    Serial.println("forward 3 revolutions");

    // # of steps forward//
    stepper.step(600);

    // turn off power to the motor then be on "ready" state //
    digitalWrite(EN1_PIN, LOW);
    digitalWrite(EN2_PIN, LOW);
    digitalWrite(DIR1_PIN, LOW);
    digitalWrite(DIR2_PIN, LOW);


  }


//// limiter switch with button2 //
  if(buttonState2 = 1 && limitsw.uniquePress()){
    analogWrite(EN1_PIN, PWM);
    analogWrite(EN2_PIN, PWM);
    stepper.setSpeed(RPM);
    Serial.println("stop button1 reverse");
    delay(100);

    Serial.println("forward 1 revolution");

    // # of steps forward//
    stepper.step(200);

    // turn off power to the motor then be on "ready" state //
    digitalWrite(EN1_PIN, LOW);
    digitalWrite(EN2_PIN, LOW);
    digitalWrite(DIR1_PIN, LOW);
    digitalWrite(DIR2_PIN, LOW);


  }





   // This is a busy-wait loop until the inter-step time passes
   stepper.step(DIR);
}



Any ideas guys?

wildbill

Firstly, = is assignment, == is comparison, so this:
Code: [Select]

  if(buttonState1 = 1 && limitsw.uniquePress())

should be
Code: [Select]

if(buttonState1 == 1 && limitsw.uniquePress())

However, note also, that you never reset buttonState1 (or 2 for that matter), so once you've pressed the button, it's stepping action will be invoked on every iteration of loop - you need an else on the checking ifs that puts it back to 0.

hun1

Gonna try it out today. I forgot about the else statement, and thanks for the == heads up.

Go Up