mini microswitch and code

Hello,

I need some advice on a project I’m working on. To be perfectly honest, today is the first time I heard about Arduino, but since there’s a limited amount of time I thought gave it a shot.

I have an Arduino Uno R3 stacked with a VMA03 Motor&Power Shield for Arduino, see the model here

I’ve connected two Stepper motors to the shield.

The motors are supposed to transport an object from one end to another and when the object reaches one end, it has to trigger a mini microswitch that will rotate the motors in opposite direction, so the object returns to the other end, where another switch is activated, etc. etc. In other words; the object needs to ‘bounce’ between to ends infinitely.

You can see the mini microswitch here

The terminal C (common) of both switches are connected with the 5v pin on the shield. The terminal N0 (Normally Open) of both switches are connected to pin A0 and A1.

This is the Code:

// Initializing pins
const int pwm_a = 3;
const int pwm_b = 9;
const int dir_a = 2;
const int dir_b = 8;

const int endstop1 = A0;           //vul hier de pin van 1 eindstop in
const int endstop2 = A1;           //vul hier de pin van andere eindstop in. ZORG DAT BEIDE ACTIEF HOOG ZIJN ANDER KLOPT CODE OVERDER NIET
const int STEPS = 2*200;      //total count of halfsteps per full rotation (*2 for half steps!)
                              // e.g. 1.8deg stepper => 200 steps => 400 halfsteps
int currStep = 0;             //current step, corresponds to angular position,  limits: 0...STEPS
int sub = 0;                  //current halfstep within repeating sequence (8 halfsteps), limits: 0...7

int richting = 0;  

int stepdelay= 10000;    //Wait time between steps (microseconds) - slow drive
//*********************************************************************************************************

void setup()
{
  // Initialize the pins, in the correct type of mode.
    pinMode(pwm_a,OUTPUT);
    pinMode(pwm_b,OUTPUT);
    pinMode(dir_a,OUTPUT);
    pinMode(dir_b,OUTPUT);
    
  // hier definieer je best de pins van de eindstops  
  
    pinMode(A0,INPUT);
    pinMode(A1,INPUT);
    
}
//*********************************************************************************************************

void loop()
{
  if (endstop1 == 1)
  {
    richting = 1;
  }
  else if (endstop2 == 1)
  {
    richting = 0;
  }
  
  if (richting == 0)
  {
    subStep(2, stepdelay);
    delayMicroseconds(stepdelay);
  }
  else if (richting == 1)
  {
    subStep(-2, stepdelay);
    delayMicroseconds(stepdelay);
  }
    
}
//*********************************************************************************************************

void TurnOfMotors(){
    digitalWrite(pwm_a,LOW);
    digitalWrite(pwm_b,LOW);
    digitalWrite(dir_a,LOW);
    digitalWrite(dir_b,LOW);
}
//*********************************************************************************************************

void subStep(long steps, int stepDelay){

    while(steps!=0)
        {

        if(steps>0){currStep++;}       //increment current halfstep (forward)
        if(steps<0){currStep--;}       //decrement current halfstep (backward)

        if(currStep>STEPS){currStep= currStep-STEPS;}         //position >360deg is reached => set position one turn back
        if(currStep<0){currStep= currStep+STEPS;}             //position <0deg   is reached => set position one turn forward

        sub = currStep%8;           //determine the next halfstep

        switch(sub)
        {
               case 0: 
        // Starting position (if repeated, ful step (4))
        // EXPLINATION: in this case, both our power are high.
        // Therefore both coils are activated, with their standard polarities for their magnetic fields.
        digitalWrite(pwm_a,HIGH);
        digitalWrite(pwm_b,HIGH);
        digitalWrite(dir_a,HIGH);
        digitalWrite(dir_b,HIGH);
                break;

                case 1:
        //Half step (½)
        // EXPLINATION: In this case, only out b-coil is active, still with it's stand polarity.
        digitalWrite(pwm_a,HIGH);
        digitalWrite(pwm_b,LOW);
        digitalWrite(dir_a,HIGH);
        digitalWrite(dir_b,LOW);
                break;

        case 2:
                //Full step (1)
        // EXPLINATION: In this case, the b-coil is activated as in previous cases.
        // But the a-coil now has it's direction turned on. So now it's active, but with the reversered polarity.
        // By continuing this pattern (for reference: http://www.8051projects.net/stepper-motor-interfacing/full-step.gif) , you'll get the axis to turn.
        digitalWrite(pwm_a,HIGH);
        digitalWrite(pwm_b,HIGH);
        digitalWrite(dir_a,HIGH);
        digitalWrite(dir_b,LOW);
                break;

        case 3:
        // Half step (1½)
        digitalWrite(pwm_a,LOW);
        digitalWrite(pwm_b,HIGH);
        digitalWrite(dir_a,LOW);
        digitalWrite(dir_b,LOW);
                break;

        case 4:
        // Full step (2)
        digitalWrite(pwm_a,HIGH);
        digitalWrite(pwm_b,HIGH);
        digitalWrite(dir_a,LOW);
        digitalWrite(dir_b,LOW);
                break;

        case 5:
        // Half step (2½)
        digitalWrite(pwm_a,HIGH);
        digitalWrite(pwm_b,LOW);
        digitalWrite(dir_a,LOW);
        digitalWrite(dir_b,LOW);
                break;

        case 6:
        // Full step (3)
        digitalWrite(pwm_a,HIGH);
        digitalWrite(pwm_b,HIGH);
        digitalWrite(dir_a,LOW);
        digitalWrite(dir_b,HIGH);
                break;

        case 7:
        // Half step (3½)
        digitalWrite(pwm_a,LOW);
        digitalWrite(pwm_b,HIGH);
        digitalWrite(dir_a,LOW);
        digitalWrite(dir_b,HIGH);
                break;
         }

        delayMicroseconds(stepDelay);        //Waiting time to next halfstep

        if(steps>0){steps--;}      //decrement of remaining halfsteps of forward rotation
    if(steps<0){steps++;}      //increment of remaining halfsteps of backward rotation
    }
}
//*********************************************************************************************************

Most of it is copypasted from a thread on another forum.
The if and if else part I wrote with a friend of mine.

richting = direction

The motors are running fine but the microswitches do not trigger anything
Is there an obvious solution for this? Something missing in the code perhaps?
Hopefully you guys can help me? Please!

Thanks in advance.

You're testing the pin number here:

  if (endstop1 == 1)

You need to use digitalRead to get the state of the pin instead.

Try making sketches to make each part work by itself first.

Thanks wildbill for the advice, not sure what it means yet, but i will look it up.

@Goforsmoke, what do you mean by each part? Try to connect and sketch only one switch first?

if (endstop1==1) is your problem.

endstop1 is set to the pin, but you're using it like you've already read the pin and stored it in endstop1.

What you want to do is read from the pin, and compare that reading - if (digitalRead(endstop1)==1)

Also, when the switch is not pushed, what's connected to the pin going to the arduino? If nothing, it won't work, because it's floating at that point - it could be high, it could be low. It'll definitely be high when the switch is closed, since it's connected to vcc, of course. What you need is a pulldown - something like a 10k resistor between ground and the wire going from switch to arduino - this will gently pull it to ground (LOW) when the switch isn't connected.

(Alternately, you can skip the resistors, use pinMode() INPUT_PULLUP, connect COM on switch to GND instead of VCC, and then invert your logic or move the wire going to arduino to the Normally Closed contact)

const int endstop1 = A0;

endstop1 is set to A0, which is defined as 14. So endstop1 = 14.

You are asking if endstop1 == 1. The answer is no, 14 never equals 1.

What you want to know is the state of pin 14, not the pin number.

So you use digitalRead to get pin states.

if(digitalRead(endstop1) == 1) {

YESS!! Thankyou! Drazzy and Delta, put in the digitalread, did the pullup and switched to the NC terminal et voila! Thanks for the quickreply!

One more question, does it matter which GND i use on the board?

rvdv: One more question, does it matter which GND i use on the board?

Nope, they are all equivalent.

rvdv: Thanks wildbill for the advice, not sure what it means yet, but i will look it up.

@Goforsmoke, what do you mean by each part? Try to connect and sketch only one switch first?

sketch: make 1 motor do exactly what you want and you know the code and circuit very well.

sketch: make 1 switch do and for that you may find that grounding an INPUT_PULLUP pin works best with fewer parts.

sketch: make a process that takes input values from variables and sets other variables as output to model what you want to do.

Along the way you may deal with timing issues and switch debouncing and logic. They will all be easier to troubleshoot in easier to control, smaller code with fewer unknowns than as one big code with multiple unknowns.

combining those to work together:

switches are inputs. switch code should run independent to everything else and set variables for other parts of the code to use.

motors are outputs. motor code should run the motors according to the values of variables that other parts of the code set to control them.

decisions are processing. decision code should read the switch states and set the motor states.

The switch, motor and decision parts can be inside of loop() together but none should be part of another. Resist that! Keep your code modular and keep the modules small if possible. Use variables to pass information and control between the parts. To change or add later, to use this as a base for more will be far easier later and by this process you can avoid writing spaghetti code. This example is very simple, as it should be, but the practice behind it is fundamental.

Right now, this is the step that I believe you would be most interested in:

sketch: make a process that takes input values from variables and sets other variables as output to model what you want to do.

About ground. The more power you use, the more grounds you want to use. Solid ground is like solid gold.

But that rule of thumb is really for things that use far more power than you can run through an Arduino. FYI, the total current for an UNO should be 200mA or less and try not to source or sink more than 20mA from any one pin.

IMO Arduino has multiple ground holes to allow more jumpers to plug in.