Folding table problem with limit switch

Hi guys, I have a problem with this project.

PROJECT : Folding table to wall
IDEA : To fold the table to wall 90 degree when not in use to save some room space

HOW IT WORKS :

  • When we press the temporary push button a 3 phase contactor is activated and deliver current to 2 power supplies.
  • the first 7 volt power supply for powering arduino and the other for powering h-bridge motor driver.
  • when the arduino powered, it will trigger an SPDT relay to hold that 3 phase contators coil remain active, and then the temporary push button can be release at this phase.
  • arduino will read if the top limit switch is triggered for more than 500 millisecond then it will start moving the table downwards while counting the encoder from 0 position.
  • when the table reach 80000 encoder counts (around 85 degree to horizontal) it will decrease the motor speed.
  • when the table touch bottom limit switch, the motor stop and brake, and then arduino release the spdt relay thus turn off everything (I mean everything).
  • when the table need to be fold to wall, the temporary push button need to be pressed again to power everything just like before.
  • the problem is : when the table reach -80000 encoder counts, it should decrease the motor speed.
  • But instead, it just read the top limit switch is in LOW condition (LOW means triggered).
  • and it stop there at 85 degree to vertical without even touch the top limit switch, and release spdt relay thus turn off everything.

here the code :

#include <Encoder.h>

Encoder myEnc(2, 13);			// QUADRATURE ENCODER CHANNEL A & B 100PPR
long oldPosition  = -999;
long int i = 5000;
int o = 1;
int LPWM = 4;               	
int RPWM = 5;
int enL = 44;
int enR = 45;
int del = 0;
int downspeed = 50;
int upspeed = 50;
int relay = 49;             		// SPDT RELAY
int LSA = 24; 				// LSA = TOP SIDE Limit Switch
int LSB = 29;				// LSB = BOTTOM SIDE Limit Switch
int LSAvalue = 0;
int LSBvalue = 0;



void setup() 

{
  delay(500);
  pinMode(LPWM, OUTPUT);		// LEFT PWM MOTOR DRIVER
  pinMode(RPWM, OUTPUT);           // RIGHT PWM MOTOR DRIVER
  pinMode(enL, OUTPUT); 		// ENABLE MOTOR DRIVER
  pinMode(enR, OUTPUT); 		// ENABLE MOTOR DRIVER
  digitalWrite(enL, HIGH);
  digitalWrite(enR, HIGH);
  pinMode(relay, OUTPUT);    	// SETUP RELAY STDP FOR HOLDING CONTACTOR
  digitalWrite(relay, HIGH);     // RELAY IN ACTIVE HIGH
  pinMode(LSA, INPUT);        	// SETUP TOP SIDE LIMIT SWITCH
  pinMode(LSB, INPUT);         // SETUP BOTTOM SIDE LIMIT SWITCH
  digitalWrite(LSA, HIGH);      // MANUALLY ADDED 10K RESISTOR FOR STRONGER PULL UP
  digitalWrite(LSB, HIGH);      // MANUALLY ADDED 10K RESISTOR FOR STRONGER PULL UP
}



void loop()

{ 
 	delay(100); 
  	LSAvalue = digitalRead(LSA);
  	if(LSAvalue == LOW)                // (WORKED FINE)
	{ 
  		delay(500);
    		LSAvalue = digitalRead(LSA);   // DOUBLE CHECKING
  		if(LSAvalue == LOW)  // (WORKED FINE) 
		{   
     		  goingdown();          // CALL GOINGDOWN FUNCTION
		  digitalWrite(relay, LOW);  // DISCONNECT POWER TO CONTACTOR THROUGH SPDT RELAY
		}
 	}
	
	LSBvalue = digitalRead(LSB);
  	if(LSBvalue == LOW)
 	{ 
    	  delay(500);
          LSBvalue = digitalRead(LSB);
    	  if(LSBvalue == LOW)     // DOUBLE CHECKING BOTTOM LIMIT SWITCH WHEN PRESSED
		{
    		  goingup();          // CALL GOINGUP FUNCTION
		  digitalWrite(relay, LOW);   // DISCONNECT POWER TO CONTACTOR THROUGH SPDT RELAY
		}
	}

void goingdown()
{  
        digitalWrite(RPWM, LOW);
 	analogWrite(LPWM, downspeed);
	for(i = 0 ; i < 100 ;)
	{    
  		long newPosition = myEnc.read();
  		if (newPosition != oldPosition) oldPosition = newPosition;
  		if(newPosition >= 40000) i = 100; // when encoder reach 80000 counts then exit for loop
	}
  
	for(i = 0 ; i < 100 ;)  // slowing down the motor to 20 pwm until bottom limit switch touched
	{
   		LSBvalue = digitalRead(LSB);
   		if(LSBvalue == LOW)             // (WORKED FINE)
		{
      			i = 100;
    		}
    		downspeed = 20;
    		digitalWrite(RPWM, LOW);
    		analogWrite(LPWM, downspeed);
    		long newPosition = myEnc.read();
    		if (newPosition != oldPosition) oldPosition = newPosition;
    		}
    		digitalWrite(RPWM, LOW);
  		digitalWrite(LPWM, LOW);
  		delay(1000);
}  

void goingup()
{  
 	analogWrite(RPWM, upspeed);
 	digitalWrite(LPWM, LOW);
 	for(i = 0 ; i < 100 ;)
  	{ 
  	  long newPosition = myEnc.read();
    	  if (newPosition != oldPosition) oldPosition = newPosition;
    	  if(newPosition <= -40000) i = 100;   // when encoder reach -80000 counts then exit for loop
	}
  
	for(i = 0 ; i < 100 ;)  //it should slowing down the motor until bottom limit switch touched
	{
    		LSAvalue = digitalRead(LSA);
    		if(LSAvalue == LOW)          // THIS IS THE PROBLEM, IT ALWAYS READ LOW    
		{
     			i = 100;
      		}
    		upspeed = 20;
    		analogWrite(RPWM, upspeed);
    		digitalWrite(LPWM, LOW);
    		long newPosition = myEnc.read();
    		if (newPosition != oldPosition) oldPosition = newPosition;
  	}
  	digitalWrite(RPWM, LOW);
  	digitalWrite(LPWM, LOW);
  	delay(1000);
}

I have a strong feeling the problem is in the code, because wiring is fine (I think)… I will try to draw the scheme if needed.
Any help appreciated…

If the switch is always reading LOW, it doesn't sounds to be a code issue... Should the switch be in HIGH, correct?

What kind of switch es are you using? HALL or contact?

Have you probed the switch with a voltmeter? Are you using pull-up/pull-down accordingly?

Finally, your "for" statement is more likely to be a "while" as you do not increment the counter "i" anywhere. You could use ”for" together with the encoder value and gradually reducing the speed... I would also check the switch state every loop instead of rely on the encoder only.

musskopf: If the switch is always reading LOW, it doesn't sounds to be a code issue... Should the switch be in HIGH, correct?

What kind of switch es are you using? HALL or contact?

Have you probed the switch with a voltmeter? Are you using pull-up/pull-down accordingly?

Finally, your "for" statement is more likely to be a "while" as you do not increment the counter "i" anywhere. You could use ”for" together with the encoder value and gradually reducing the speed... I would also check the switch state every loop instead of rely on the encoder only.

Hi musskopf, thanks for reply...

I already check the switch (contact switch) with voltmeter and also create seperate coding to test the switch and the result is fine... Read high when switch open and read low when switch closed.

I am using 10k pull up resistor on both switch.

The reason I didn't include "digitalWrite" or "digitalRead" inside encoder counter reading loop is because I'm affraid it will be slowing down the uC in counting the encoder thus result miss steps. I am using 3000 rpm motor 24v 10A and use 2 pcs 1: 30 worm gearboxes coupled together (cannot lift the table only with 1 gearbox). Should I try include digitalRead and digitalWrite inside the counter loop?

I think I found the problem after testing which one causing that digital input triggered. Whenever power supply for the motor driver is turned on, that digital input is become sensitive (I already put 2K pull up resistor on that digital input pin), I just need to touch the pin cable to trigger it (put my hand close to it won't trigger it). But if the power supply off, the pin back to normal...

And then I try release cable from power supply of the motor driver (VDC side), when power supply on it still triggered sometimes (the cable just like an antenna, but it is hooked on motor driver right?). And then I move the cable away from power supply and motor driver and it works. Is it motor driver broken? But it still drive the motor good. Or the power supply have problems?

Please help me guys...

Have you tried to use a debouce circuit? A 10k, 100k and 0.1uf worked fine for a digital input I had on a garage door motor with similar problem.

If you never used one, just google it and get some examples... The idea is to remove any high frequency switching.

First I try to change a better quality power supply to motor driver, and it looks better but the problem not solved (only better). And then I try to remove the 3 phase contactor (which making a little humming sound), turns out more better. Last thing is I remove the arduino power supply, and change it with dc-dc step down from 12V motor power supply to 7V arduino. Now everything is good. But I think I have to try debounce circuit just like you suggest for digital input stability, thanks for your patience answering me... God bless you