Help with buttons that control stepper motors

Through the help of you fine folks in these forums, I was able to create a project that controls two stepper motors to move a table from normal position to upright against a wall via leadscrews and linear slides. I have a button to move the motors clockwise (up), counter-clockwise (down) and then a button to "stop" manually and then a limit switch for the up position and then one for the down position. This all worked well via breadboard and simulated function. Now that the table is installed and all wired up, the buttons aren't functioning properly. I've been reading about debounce and am wondering if that could be part of my problem? The distance between the arduino and the buttons is about 10 ft and I'm using a breakout board via rj45 and an ethernet cable to carry the signal. Pushing the buttons doesn't seem to do much (occasionally it will start up, but it will randomly stop etc). It's just very inconsistent. And I can't seem to send the table back down regardless if I just jump from ground to the input pin for down.

Below is a screenshot of my wiring diagram and then also the first part of my code. Thank you!!


What is the reason the distance between the arduino and the buttons are so far apart? What type of cables are you using?

How is the Arduino, stepper motor, stepper motor driver powered?

You mention "breakout board via rj45 and an ethernet cable to carry the signal", that is not in your diagram, so it's difficult for anyone to imagine what your set up looks like, please show a detailed diagram on the entire wiring.

FYI: whenever posting code, you should use "code tags" instead of a screenshot.

You definitely need pull-up resistors and debouncing.

Say, that looks like you've done some work with the wokwi.com simulator.

If so, woyncha post a link to that so we can see it and play with our own copy?

You can use the "share" button. Don't worry, we can't mess with your copy.

a7

Thank you @arduinobotting . I'll try to address all of your points. This is for a CNC machine on a table that automatically stowes away in my garage. The arduino is mounted under the machine and to route the cable up to the bottons (on the side of the table), I had to use a 10' ethernet cable. It's a CAT6 cable I'm just using the ground from the arduino on pin 1 and then jumping it to the input of all 3 buttons, and then the output of each button goes back through the cable to the inputs on the arduino.

I'm using two stepper motors connected to a stepperonline DM542T driver, connected to a 10A 24v power supply.

I just came up with the breakout board option a day ago as it seemed as a good way to carry the signal on multiple cables easily. I'll try to add the breakout to the diagram. Essentially it's connected the same. Technically since I'm using ground as my input signal, shouldn't I just be able to run a jumper to the input pins on the arduino to trigger (simulating a button press)?

I apologize for the formatting of the code. I will attach that here. I have also attached some pictures and videos (just realized videos are not allowed, so linking to them...hope that is ok) for clarification.
CAD simulation
Actual table motion

// Define pins for stepper motor control
#define DIR_PIN         8
#define STEP_PIN        9

// Define pins for buttons and limit switches
#define UP_BUTTON       2
#define DOWN_BUTTON     3
#define STOP_BUTTON     4
#define LIMIT_SWITCH_1  5
#define LIMIT_SWITCH_2  6

enum MotorStates
{
    STOPPED=0,
    MOVING
};

#define BTN_PRESSED     LOW
#define LIMSW_PRESSED   LOW

const uint32_t kFadeTime = 3000000ul;   //3-second ramp time
const uint32_t kInitSpeed = 1000ul;     //2x == uS/step
const uint32_t kFinalSpeed = 250ul;     //2x == uS/step
const uint32_t kAccelDelay = (uint32_t)(kFadeTime / (kInitSpeed - kFinalSpeed) );
uint32_t 
    ulStepDelay,
    tNow,
    tAccel = 0ul;
bool
    bAccel;

void setup() 
{
    // Set pins for motor control as output
    pinMode(DIR_PIN, OUTPUT);
    pinMode(STEP_PIN, OUTPUT);
    
    // Set pins for buttons and limit switches as input
    pinMode(UP_BUTTON, INPUT_PULLUP);
    pinMode(DOWN_BUTTON, INPUT_PULLUP);
    pinMode(STOP_BUTTON, INPUT_PULLUP);
    pinMode(LIMIT_SWITCH_1, INPUT_PULLUP);
    pinMode(LIMIT_SWITCH_2, INPUT_PULLUP);
    
    // Set initial state of DIR_PIN to LOW
    digitalWrite(DIR_PIN, LOW);

    bAccel = false;
    
}//setup

void loop() 
{
    static uint8_t
        motorState = STOPPED,
        pinLimit;
            
    if( digitalRead( STOP_BUTTON ) == BTN_PRESSED )
    {
        motorState = STOPPED;
    }

    switch( motorState )
    {
        case    STOPPED:
            if( digitalRead( UP_BUTTON ) == BTN_PRESSED )
            {
                digitalWrite(DIR_PIN, LOW);
                pinLimit = LIMIT_SWITCH_1;
                ulStepDelay = kInitSpeed;
                tAccel = micros();
                bAccel = true;
                motorState = MOVING;
                
            }//if
            else if( digitalRead( DOWN_BUTTON ) == BTN_PRESSED )
            {
                digitalWrite(DIR_PIN, HIGH);
                pinLimit = LIMIT_SWITCH_2;
                ulStepDelay = kInitSpeed;
                tAccel = micros();
                bAccel = true;
                motorState = MOVING;
                
            }//if
            
        break;
        
        case    MOVING:
            tNow = micros();
            if( bAccel )
            {                
                if( (tNow - tAccel) >= kAccelDelay )
                {
                    tAccel = tNow;
                    ulStepDelay--;
                    if( ulStepDelay == kFinalSpeed )
                        bAccel = false;
                        
                }//if
                
            }//if
            
            if( digitalRead( pinLimit ) != LIMSW_PRESSED )
            {
                digitalWrite(STEP_PIN, HIGH);
                delayMicroseconds(ulStepDelay);
                digitalWrite(STEP_PIN, LOW);
                delayMicroseconds(ulStepDelay);
                
            }//if
            else
            {
                motorState = STOPPED;
            }//if
            
        break;
        
    }//switch
    
}//loop


2
3

Thanks @alto777 , I shared some links previously and apparently broke a rule, so I was apprehensive about doing that. But that makes things much easier. Please see attached link. I also attached some additional pictures and and link to videos as well as the code above if that helps as well. Thank you!!

Well it was my understanding that if I'm using ground for the inputs on the arduino, that I can use the internal pullup via the code and not need to physically add a resistor. Did I not understand that properly?

No that is correct. I number myself among the people who lived before the miracle of internal pull-ups, before most miracles TBH, and will always use an external resistor to do the work.

And in some cases, the internal pull is weak, too weak, and a hefty (lower value) pullup is required. Like long leads that might pick up enough noise to appear as valid signals.

Of course wokwi is perfect, no need to use a resistor.

And imperfect - you can wire up LEDs with no series current limiting resistor and never burn one out…

THX for the link BTW. On the beach now, I play later.

a7

Yes and No.
If everything is on the same PCB board, then it's safe to use the internal pull-ups but if your push buttons are on 10' wires, then you need an external pull-up. It has to do with the extra inductance and capacitance of the wires and the possibility of noise pick-up.
Use 2.7K or 3.3K.
Don't forget the debouncing. There is an example in the IDE under Files-Examples-Digital

I haven't looked to see if it will be needed.

@crankycowboy once again, wokwi is good for this... if your switches are not doing what you think they should, or what you want them to do, it may be contact bounce.

wokwi lets you check this easily. Click on a pushbutton and then in the dialog that pops up, uncheck the "Bounce" parameter.

Instant perfect non-bouncing switches.

When/if that settles your issue, begin the changes to do the debouncing that real life needs.

There are many ways to denounce a pushbutton, not all software.

Unfortunatley slide switches in wokwi do not appear to have a pop-up for this, but they do have an attribute you can place in the diagram.json file, viz:

 { "bounce": "0" }

which you can do like

    { 
      "type": "wokwi-slide-switch",
      "id": "sw1",
      "top": -206.8,
      "left": 204.7,
      "attrs": { "bounce": "0" }
    }

Losing the bounce attribute or setting it to "1" brings back the simulated contact bounce.

HTH

a7

The wowoki sketch referenced has bounce enabled for the switches. It does not appear to be an issue.
My analysis of the flow of the sketch also leads me to think that bounce is not an issue.

Pushing the buttons doesn't seem to do much (occasionally it will start up, but it will randomly stop etc). It's just very inconsistent. And I can't seem to send the table back down regardless if I just jump from ground to the input pin for down.

This does not sound like switch bounce to me.

shouldn't I just be able to run a jumper to the input pins on the arduino to trigger (simulating a button press)?

Yes.

Thanks @cattledog . So initially (even on this table), I connected a breadboard with micro buttons and limit switches connected very close to the arduino. All worked exactly as expected. I disconnected all of that, and extended the wires....now everything is going "wacky". I've disconnected all of the inputs and only left the pulse and direction output wires. I then tried to just run a jumper from ground to the "up" input and nothing happens (and this is right at the arduino). I've verified continuity between the dir and pul pins and the actual motor drivers and all is connected. I'm very confused as to what to try next.

Can you get back to this situation?

I've disconnected all of the inputs and only left the pulse and direction output wires. I then tried to just run a jumper from ground to the "up" input and nothing happens (and this is right at the arduino).

This would say that the issue is not with the buttons, but an issue with the steppers running in the new configuration.

There have been quite a few reports about bad breadboards with intermittent connections.
Also note some have a split ground and power rail that is not continuous from one end of the board to the other.

There is certainly some odd behavior. I can't seem to make my "dir" pin go from high to low no matter what I try. I think I'm going to do as you suggest and try to replicate the basic setup I had previously. Part of the difficulty is that I've already soldered and heat shrinked motor wires etc. I think I may just decouple the motor from the screws to see if I can make the motor turn without having to worry about limit switches and stopping before a hardware max limit situation. I'll start there.

Thanks @jim-p ....that's actually the opposite of my problem. All worked as expected on the breadboard.....but not functioning properly after connecting to terminal blocks etc. I actually did it right and have ferrulled connections, terminal blocks with block jumpers etc, soldered wires etc.

Geez guys @alto777 , @jim-p , @cattledog , @arduinobotting , I figured out my problem. I'm an idiot....that's #1 lol. I was using the common from my 24v power supply to the stepper drivers for the pul - and dir - instead of the gnd from the arduino. I REALLY appreciate all of you guys taking the time in trying to help me out. THANK YOU!

Yeah none of us has ever done anything nearly so dumb. :wink:

a7

Uh, no. There is a new user limit which disappears at something like five posts. As long as it's on topic link away.

For a long running project it's helpful to link to previous threads. That allows those trying to help to have some background. An example...

RE: Stepper Motors, Limit Switches and buttons

Maybe I misunderstood what I was being told, but I could have sworn I was told not to link to other sites. Sorry for the confusion.

That actually makes sense. I apologize I didn't do that. I will certainly do that moving forward. Thank you for the input @Coding_Badly

1 Like