Limit switches to trigger forward and reverse movement of motor

I am fairly new to the Arduino and need help developing a code that enables a mobile object to move between two limit switches continuously. In the final code there will be four individual mobiles that will each have 2 limit switches that guide their movement up and down, but once I have code for 1 mobile I assume I can copy and apply it to the others.

Here is the algorithm: When the top limit switch (limitsw_u1) is pressed it triggers and sustains the state of downward movement until the bottom limit switch (limits_d1) is pressed which triggers and sustain the state of upward movement. This repeats.

Here is a video of a similar type of function: Forward/Reverse Direction control of Induction motor using Limit Switches - YouTube

As for the limit switches, what is the proper way of wiring them into this circuit (i've attached a photo of my limit switch)? I was attaching 5v to the common, and attaching a wire from NO to an input pin.

Here is the code I used (i've also attached it, if that is easier). Note, as I am fairly new to the arduino, some of the code language is probably not used correctly:

arduino.relay.doug.sketch_may19a.ino (2.02 KB)

You will want to closely examine the forum section on "Demonstration code for several things at the same time". You cannot just duplicate the code for each device. At some point, you will be processing one limit switch change while another switch is toggled and the program will not recognize it. You want to avoid overrun conditions where the device drives into the limit switch and destroys it's mounting.

Another consideration is "initial conditions". How will you get your devices to begin moving in a known direction when the program begins execution?

Paul

Link to several things at a time

Your code needs to have a variable to record the state of the system - perhaps moveDirection = 'L';

Then the limit switch causes that to change to moveDirection = 'R';

and your motor control code will check the variable - something like this

void moveMotor() {
  if (moveDirection == 'L') {
    // make motor go left
  }
 else {
    // make motor go right
  }
}

The code in loop() could be like this

void loop() {
   readSwitches();
   moveMotor();
}

...R

1 Like

Thank-you Paul and Robin for your help. I have read the forum page "Demonstration code for several things at once" and just need some help adjusting this code. This code works with one loop consisting of 2 limit switches and the relays which guide the motor, but I need to adjust it so it complies more so with the way Robin2 has organized things, mainly in and after the void loop.

It seems the way I am recording the state of the individual systems is working, but will it work when I add the other systems or should I adjust it to what Robin2 suggested?

My main question is how do I implement this in my sketch:

void loop() {
readSwitches(); //what statement should I use for this to coordinate with my language?
moveMotor();
}

do I read ALL the switches and their current states first (readSwitches), then after that write to move all the motors (moveMotor). If someone could help me with what this looks like, that would be awesome!

Thank-you very much robin2 for the forum page, I just need to get my head around this kind of organizing (it seems it will make things simpler once I grasp it).

Here is the code: (perhaps ignore int and setup as I have not included most of the constant and variables in this code yet.

//constants
const int up1           =13;  //relays that trigger movement of DC motor
const int down1         =12;
const int up2           =11;
const int down2         =10;
const int up3           =9;
const int down3         =8;
const int up4           =7;
const int down4         =6;

const int limitsw_u1    =5;  // input switches that change movement of DC motor
const int limitsw_d1    =4;
const int limitsw_u2    =3;
const int limitsw_d2    =2;
const int limitsw_u3    =1;
const int limitsw_d3    =0;
const int limitsw_u4    =A5;
const int limitsw_d4    =A4;

const int changeDuration = 500; //amount of delay time for reversal

//variables will change 


int limitsw_u1_State  = 0;  // used to record which direction the mobile is moving
int limitsw_d1_State  = 0;
int limitsw_u2_State  = 0;
int limitsw_d2_State  = 0; 
int limitsw_u3_State  = 0; 
int limitsw_d3_State  = 0;
int limitsw_u4_State  = 0; 
int limitsw_d4_State  = 0;




void setup() {
  // relays
  pinMode(up1, OUTPUT);        //Que relays (7&8) to rotate motor.1 counterclockwise
  pinMode(down1, OUTPUT);      //Que relays (5&6) to rotate motor.1 clockwise
  pinMode(up2, OUTPUT);        // Relays    (1&2)
  pinMode(down2, OUTPUT);      // Relays    (3&4)
  pinMode(up3, OUTPUT);        // Relays    (7&8)
  pinMode(down3, OUTPUT);      // Relays    (5&6)
  pinMode(up4, OUTPUT);        // Relays    (1&2)
  pinMode(down4, OUTPUT);      // Relays    (3&4)
  // limit switches
  pinMode(limitsw_u1, INPUT);   //Up limitswitch on motor.1  breadpin (
  pinMode(limitsw_d1, INPUT);   //Down limitswitch 1         breadpin (
  pinMode(limitsw_u2, INPUT);   //Up limitswitch on motor.2  breadpin (
  pinMode(limitsw_d2, INPUT);   //Down limitswitch 2         breadpin (
  pinMode(limitsw_u3, INPUT);   //Up limitswitch on motor.3  breadpin (
  pinMode(limitsw_d3, INPUT);   //Down limitswitch 3         breadpin (
  pinMode(limitsw_u4, INPUT);   //Up limitswitch on motor.4  breadpin (
  pinMode(limitsw_d4, INPUT);   //Down limitswitch 4         breadpin (
  
  Serial.begin(9600);          //Initialize Serial connection
}



void loop() //mobile 1

{
 limitsw_u1_State = digitalRead(limitsw_u1);
 {

 // check if the pushbutton is pressed.
 // if it is, the buttonState is HIGH:
 if (limitsw_u1_State == HIGH)
while((limitsw_d1_State = digitalRead(limitsw_d1)) != HIGH)  {     
   // turn motor counterclockwise on:    
   digitalWrite(up1, HIGH);
   digitalWrite(down1, LOW);
 }
 {
 limitsw_d1_State = digitalRead(limitsw_d1);
 {
   if (limitsw_d1_State == HIGH)
 while((limitsw_u1_State = digitalRead(limitsw_u1)) != HIGH) {
   // rotate clockwise slow speed
   digitalWrite(down1, HIGH);
   digitalWrite(up1, LOW);
   
   }
 }
 }
 }}

One additional comment. On your original program, you were attempting to debounce the limit switches. With your implementation, that is not needed. The reason for debounce is when your program has very little work to do and will quickly test the switch multiple times. Your program only needs to test a limit switch that will become active in the direction the box is moving and unless it is moving very, very fast any bouncing will be long gone.

Also, you will probably need to stop the box movement before beginning to move in the opposite direction.

Paul

leviglass:
do I read ALL the switches and their current states first (readSwitches), then after that write to move all the motors (moveMotor). If someone could help me with what this looks like, that would be awesome!

YES.

You will learn more if you make the first attempt at this. I have already given you the basics of the moveMotor() function. You just need to add code for the second motor.

If you can't get it to work then post your code and we will try to help.

Generally speaking do not use WHILE for any loop that will take more than a few microseconds to complete unless there is nothing else that can be done before it finishes.

You may get more ideas from Planning and Implementing an Arduino Program - Programming Questions - Arduino Forum

...R

I have attempted to read ALL the switches and their current states first [ (limits_u1_State = digitalRead(limits_u1); ] then move the first motor function [ void moveMotor1() ] but I can't seem to get it working. I believe I am properly recording the states of the limit switches, and I tried implemented the if {} else {} statements and many variations of it instead of while{}...

Here is the main part of the code I am working on:

void loop() //mobile 1
{                                             //call the functions that do the work
 limitsw_u1_State = digitalRead(limitsw_u1);  // check if the pushbutton is pressed.
 limitsw_d1_State = digitalRead(limitsw_d1);  // if it is, the buttonState changes to HIGH:
 digitalRead(limitsw_u2_State);  
 digitalRead(limitsw_d2_State);
 digitalRead(limitsw_u3_State);
 digitalRead(limitsw_d3_State);
 digitalRead(limitsw_u4_State);
 digitalRead(limitsw_d4_State);
}
 
 //====================
 
 void moveMotor1(){
 
 if (limitsw_u1_State == HIGH) //upward limitswitch pressed
 {
   digitalWrite(down1, HIGH);  //make motor1 go down
   digitalWrite(up1, LOW);
 }
 else if (limitsw_d1_State == HIGH) //downward limit switch pressed
 {
   digitalWrite(up1, HIGH);    //make motor1 go up
   digitalWrite(down1, LOW);
 }
 }

And here is the full (very long) code from the beginning:

//constants
const int up1           =13;  //relays that trigger movement of DC motor
const int down1         =12;
const int up2           =11;
const int down2         =10;
const int up3           =9;
const int down3         =8;
const int up4           =7;
const int down4         =6;

const int limitsw_u1    =5;  // input switches that change movement of DC motor
const int limitsw_d1    =4;
const int limitsw_u2    =3;
const int limitsw_d2    =2;
const int limitsw_u3    =1;
const int limitsw_d3    =0;
const int limitsw_u4    =A5;
const int limitsw_d4    =A4;

const int changeDuration = 500; //amount of delay time for reversal

//variables will change 


byte limitsw_u1_State  = LOW;  // used to record which direction the mobile is moving
byte limitsw_d1_State  = LOW;
byte limitsw_u2_State  = LOW;
byte limitsw_d2_State  = LOW; 
byte limitsw_u3_State  = LOW; 
byte limitsw_d3_State  = LOW;
byte limitsw_u4_State  = LOW; 
byte limitsw_d4_State  = LOW;




void setup() {
  // relays
  pinMode(up1, OUTPUT);        //Que relays (7&8) to rotate motor.1 counterclockwise
  pinMode(down1, OUTPUT);      //Que relays (5&6) to rotate motor.1 clockwise
  pinMode(up2, OUTPUT);        // Relays    (1&2)
  pinMode(down2, OUTPUT);      // Relays    (3&4)
  pinMode(up3, OUTPUT);        // Relays    (7&8)
  pinMode(down3, OUTPUT);      // Relays    (5&6)
  pinMode(up4, OUTPUT);        // Relays    (1&2)
  pinMode(down4, OUTPUT);      // Relays    (3&4)
  // limit switches
  pinMode(limitsw_u1, INPUT);   //Up limitswitch on motor.1  breadpin (
  pinMode(limitsw_d1, INPUT);   //Down limitswitch 1         breadpin (
  pinMode(limitsw_u2, INPUT);   //Up limitswitch on motor.2  breadpin (
  pinMode(limitsw_d2, INPUT);   //Down limitswitch 2         breadpin (
  pinMode(limitsw_u3, INPUT);   //Up limitswitch on motor.3  breadpin (
  pinMode(limitsw_d3, INPUT);   //Down limitswitch 3         breadpin (
  pinMode(limitsw_u4, INPUT);   //Up limitswitch on motor.4  breadpin (
  pinMode(limitsw_d4, INPUT);   //Down limitswitch 4         breadpin (
  
  Serial.begin(9600);          //Initialize Serial connection
}



void loop() //mobile 1
{                                             //call the functions that do the work
 limitsw_u1_State = digitalRead(limitsw_u1);  // check if the pushbutton is pressed.
 limitsw_d1_State = digitalRead(limitsw_d1);  // if it is, the buttonState changes to HIGH:
 digitalRead(limitsw_u2_State);  
 digitalRead(limitsw_d2_State);
 digitalRead(limitsw_u3_State);
 digitalRead(limitsw_d3_State);
 digitalRead(limitsw_u4_State);
 digitalRead(limitsw_d4_State);
}
 
 //====================
 
 void moveMotor1(){
 
 if (limitsw_u1_State == HIGH) //upward limitswitch pressed
 {
   digitalWrite(down1, HIGH);  //make motor1 go down
   digitalWrite(up1, LOW);
 }
 else if (limitsw_d1_State == HIGH) //downward limit switch pressed
 {
   digitalWrite(up1, HIGH);    //make motor1 go up
   digitalWrite(down1, LOW);
 }
 }

This other code that is designed for 1 motor function still works whenever I plug it in to check if the system is working:

{
 limitsw_u1_State = digitalRead(limitsw_u1);
 {

 // check if the pushbutton is pressed.
 // if it is, the buttonState is HIGH:
 if (limitsw_u1_State == HIGH)
while((limitsw_d1_State = digitalRead(limitsw_d1)) != HIGH)  {     
   // turn motor counterclockwise on:    
   digitalWrite(up1, HIGH);
   digitalWrite(down1, LOW);
 }
 {
 limitsw_d1_State = digitalRead(limitsw_d1);
 {
   if (limitsw_d1_State == HIGH)
 while((limitsw_u1_State = digitalRead(limitsw_u1)) != HIGH) {
   // rotate clockwise slow speed
   digitalWrite(down1, HIGH);
   digitalWrite(up1, LOW);
   
   }
 }
 }
 }}

Paul_KD7HB:
Also, you will probably need to stop the box movement before beginning to move in the opposite direction.

Paul

It doesn't seem like I need a stop function before beginning to move in the opposite direction. I have tested the last code I posted with the motor and mobile object and it seems to reverse fine.

leviglass:
It doesn't seem like I need a stop function before beginning to move in the opposite direction. I have tested the last code I posted with the motor and mobile object and it seems to reverse fine.

The mass must be pretty low. You might want to measure the current draw for the motor when you reverse, and then multiply by 4 in case you reverse all motors at the same time. Be sure there is power enough.

Paul

This code is working to a degree. Motor1 (involving both limitswitches (u1/d1) and relay pins (up1/down1) is working perfectly, but there is a major delay in the response of Motor 2 (up1/down2).

Robin2
One of the things I could not figure out was how to make the digital-read section that immediately follows the void loop its own enclosed function {} and then how to make the following functions as variables of this initial read.

for exp. in the several things at a time forum you have

void loop() {

readButton();
updateOnBoardLedState();
//...
}

//then

void updateOnBoardLedState()

//which then explains the (if) function.

I have tried many times to do a similar thing with my sketch but can't seem to make it work

Here is the sketch:

//constants
const int up1           =13;  //relays that trigger movement of DC motor
const int down1         =12;
const int up2           =11;
const int down2         =10;
const int up3           =9;
const int down3         =8;
const int up4           =7;
const int down4         =6;

const int limitsw_u1    =5;  // input switches that change movement of DC motor
const int limitsw_d1    =4;
const int limitsw_u2    =3;
const int limitsw_d2    =2;
const int limitsw_u3    =1;
const int limitsw_d3    =0;
const int limitsw_u4    =A5;
const int limitsw_d4    =A4;

const int changeDuration = 500; //amount of delay time for reversal

//variables will change 

byte limitsw_u1_State  = LOW;  // used to record which direction the mobile is moving
byte limitsw_d1_State  = LOW;
byte limitsw_u2_State  = LOW;
byte limitsw_d2_State  = LOW; 
byte limitsw_u3_State  = LOW; 
byte limitsw_d3_State  = LOW;
byte limitsw_u4_State  = LOW; 
byte limitsw_d4_State  = LOW;

void setup() {
  // relays
  pinMode(up1, OUTPUT);        //Que relays (7&8) to rotate motor.1 counterclockwise
  pinMode(down1, OUTPUT);      //Que relays (5&6) to rotate motor.1 clockwise
  pinMode(up2, OUTPUT);        // Relays    (1&2)
  pinMode(down2, OUTPUT);      // Relays    (3&4)
  pinMode(up3, OUTPUT);        // Relays    (7&8)
  pinMode(down3, OUTPUT);      // Relays    (5&6)
  pinMode(up4, OUTPUT);        // Relays    (1&2)
  pinMode(down4, OUTPUT);      // Relays    (3&4)
  // limit switches
  pinMode(limitsw_u1, INPUT);   //Up limitswitch on motor.1  breadpin (
  pinMode(limitsw_d1, INPUT);   //Down limitswitch 1         breadpin (
  pinMode(limitsw_u2, INPUT);   //Up limitswitch on motor.2  breadpin (
  pinMode(limitsw_d2, INPUT);   //Down limitswitch 2         breadpin (
  pinMode(limitsw_u3, INPUT);   //Up limitswitch on motor.3  breadpin (
  pinMode(limitsw_d3, INPUT);   //Down limitswitch 3         breadpin (
  pinMode(limitsw_u4, INPUT);   //Up limitswitch on motor.4  breadpin (
  pinMode(limitsw_d4, INPUT);   //Down limitswitch 4         breadpin (
  
  Serial.begin(9600);          //Initialize Serial connection
}



void loop() 

  //call the functions that do the work
{         
 limitsw_u1_State = digitalRead(limitsw_u1);  // check if the pushbutton is pressed.
 limitsw_d1_State = digitalRead(limitsw_d1);  // if it is, the buttonState changes to HIGH:
 limitsw_u2_State = digitalRead(limitsw_u2); 
 limitsw_d2_State = digitalRead(limitsw_d2);
 limitsw_u3_State = digitalRead(limitsw_u3);
 limitsw_d3_State = digitalRead(limitsw_d3);
 limitsw_u4_State = digitalRead(limitsw_u4);
 limitsw_d4_State = digitalRead(limitsw_d4); 


 //interpret signals into variables
 //1
 if (limitsw_u1_State == HIGH) //upward limitswitch pressed
 {
   downward1();
 }
 if (limitsw_d1_State == HIGH) //downward limit switch pressed 
 {
   upward1();
 }
 
 //2
  if (limitsw_u2_State == HIGH) //upward limitswitch pressed
 {
   downward2();
 }
 if (limitsw_d2_State == HIGH) //downward limit switch pressed 
 {
   upward2();
 }
 
 //3
 
  if (limitsw_u3_State == HIGH) //upward limitswitch pressed
 {
   downward3();
 }
 if (limitsw_d3_State == HIGH) //downward limit switch pressed 
 {
   upward3();
 }
 
 //4
 
  if (limitsw_u4_State == HIGH) //upward limitswitch pressed
 {
   downward4();
 }
 if (limitsw_d4_State == HIGH) //downward limit switch pressed 
 {
   upward4();
 }
 }
 
 // write variables as functions 
 void downward1()
 {
   digitalWrite(up1, LOW);      //pause to allow motors to switch
   digitalWrite(down1, HIGH);  //make motor1 go down
 }
 void upward1()
 {
   digitalWrite(down1, LOW);
   digitalWrite(up1, HIGH);    //make motor1 go up
 }
  void downward2()
 {
   digitalWrite(up2, LOW);
   delay(changeDuration);      //pause to allow motors to switch
   digitalWrite(down2, HIGH);  //make motor2 go down
 }
 void upward2()
 {
   digitalWrite(down2, LOW);
   delay(changeDuration);
   digitalWrite(up2, HIGH);    //make motor2 go up
   
 } 
 void downward3()
 {
   digitalWrite(up3, LOW);      //pause to allow motors to switch
   digitalWrite(down3, HIGH);  //make motor3 go down
 }
 void upward3()
 {
   digitalWrite(down3, LOW);
   digitalWrite(up3, HIGH);    //make motor3 go up
   
 } void downward4()
 {
   digitalWrite(up4, LOW);      //pause to allow motors to switch
   digitalWrite(down4, HIGH);  //make motor4 go down
 }
 void upward4()
 {
   digitalWrite(down4, LOW);
   digitalWrite(up4, HIGH);    //make motor4 go up
 }

Something like this ...

void loop()

  //call the functions that do the work
{         
   readSwitches();


 //interpret signals into variables
 //1
 if (limitsw_u1_State == HIGH) //upward limitswitch pressed
 {
   downward1();
 }
 if (limitsw_d1_State == HIGH) //downward limit switch pressed
 {
   upward1();
 }
  // etc
 }

void readSwitches() {
 limitsw_u1_State = digitalRead(limitsw_u1);  // check if the pushbutton is pressed.
 limitsw_d1_State = digitalRead(limitsw_d1);  // if it is, the buttonState changes to HIGH:
 limitsw_u2_State = digitalRead(limitsw_u2);
 limitsw_d2_State = digitalRead(limitsw_d2);
 limitsw_u3_State = digitalRead(limitsw_u3);
 limitsw_d3_State = digitalRead(limitsw_d3);
 limitsw_u4_State = digitalRead(limitsw_u4);
 limitsw_d4_State = digitalRead(limitsw_d4);
}

You won't get a responsive program if you use delay() to manage timing. You need to use millis() as illustrated in several things at a time.

...R