Controlling a stepper w/foot pedal & park position

What I'd like help with from the community: (see bottom of message, above edits)

Images in POST #10
Wiring Diagram in POST#11

What I'm trying to do (condensed):

  • control a stepper to start and stop when I tell it to and always continue returning until it reaches "home"
  • variable speed with foot pedal while its supposed to run

My experience:

  • I'm new to Arduino
  • No experience with C++
  • Limited experience with other program languages, mostly HTML and recovering vintage Dell Latitude D-series brick laptops.
  • LOTS of electrical experience
  • very limited no electrical experience with chips and transistor arrays (count it as nil)
  • extremely high level of ability and experience with anything mechanical and physical, including solving issues others can't. (but not when it comes to code lol)

What I'm trying to do (expanded)

  • I'm trying to run a stepper motor that is belt driven at a variable speed controlled by a foot pedal control and have it return to home. The stepper will drive the object via a cogged timing belt but has the potential to occasionally slip since the driving end of the belt will be in contact with the smooth side of the belt so I want to place a microswitch on the driven component to tell the stepper it has reached "home". I want to microswitch to do nothing while the foot pedal is in operation though. I want the Arduino to hold the stepper in place when its powered on but has the foot pedal disabled. I want a knob for both the low and the high motor speed limit speeds (these will be inside my final enclosure so they don't get messed with by other people or accidentally bumped.

What I've tried:

  • I've searched the internet for many hours on how to make this work and keep finding snippets of code but can't seem to figure out how to like them together. I've played with basic Arduino codes and successfully uploaded them and tinkered with changing elements to change the outcomes. I've not determined if I need to supply the motor shield with 5V or 12V.
    I haven't determined what pins connect to what motor shield connections. I think I have a basic enough design that I can use a single transistor assy. on the breadboard to do what I need but am not sure of this. I think I need to purchase a 2004 transistor assy. for hooking up my motor since my motor is a 4-wire.

What I have:

  • Arduino Uno R3
  • Arduino MEGA 2650 R3
  • NEMA 23 stepper motor, bipolar, 2.8A, 4-wire [Link (NON-affiliate)](JoyNano Nema 23 Stepper Motor Bipolar 2.8A 1.89N.m Holding Torque 2-Phase 4-Wire 1.8 Deg 76mm Body for 3D Printer or CNC Machine Amazon.com)
  • NEMA 17 Stepper motors (spares for my Creality CP-01 3-in-1 3D printer)
  • TB6600 NEMA stepper motor driver, 4A [Link (NON-affiliate)](Usongshine TB6600 4A 9-42V Nema 17 Stepper Motor Driver CNC Controller Single Axes Phase Hybrid Stepper Motor for CNC/42 57 86 Stepper Motorļ¼ˆ1 pcs) Amazon.com)
  • Motor shield for Arduino Uno
  • 5V power supply(s)
  • 12V power supply(s)
  • Cogged 10mm timing belt
  • micro switches (momentary, NO)
  • variable resistor foot pedal
  • Relay shield for Arduino Uno
  • Prototyping Shield for Arduino Uno

How I want it to work:

  1. plug in Arduino
  • power to Arduino, lock stepper in place
  1. push button
  • turn "on", motor not moving (yet) [permit foot pedal control]
  1. variable foot pedal input
  • change speed of motor in relation to how much I push on the foot pedal, with a small area at the start of pushing that the motor stays still
  1. release foot pedal
  • motor continue to turn, but at predetermined minimum speed until it reaches "home"
  1. push button
  • disable foot pedal (keep Arduino on but prevent motor from turning, lock stepper in position)
  1. IF: push added "home" button
    THEN: move stepper at predetermined minimum speed until it reaches home (this would be for if I managed to knock the stepper out of home (I don't want it to try this without me telling it to do so because I don't want my hand in the way)
  2. unplug arduino
  • turn system off completely, stepper unlocked

If anyone can help with this code and how to properly connect (motor shield vs breadboard, 5v/12v supply to shield/breadboard, required chips, etc) it would be greatly appreciated.
If I can get it together, I'll post my project here for you all to see the finished project, a lot of us that use a lot of small wires could really appreciate this tool when its done!

I'll try to post how it's coming as I get help and clarify any questions you have for me to the best of my ability. In the meantime, I'll be 3D printing & laser cutting the main components of the project and assembling them.

Thanks in advance for any help!

EDITS:
10-06-2023 @ 8:45pm

  1. Motor must continue "forward" until it reaches "home", it cannot back up in the final design.
  2. Motor type and size is open for a change in the end, NEMA 17 can work but an upgrade would likely occur. motor could be DC geared if "self-locking", quiet, and stops predictably with long service life. Typically NEMA steppers meet these specs whereas DC gear motors don't always.

10-08-2023 @ 12:42am

  1. I have settled on a belt drive (with a tensioner (Thanks @Paul_KD7HB)) due to a few constraints:
  • A direct contact wheel with the stepper would stop moving every time the opening came around because it would lose contact
  • A gear drive would stop moving every time the opening came around because the gear teeth would not be in contact.

10-08-2023 @ 1:25pm

  1. I have added pictures to this project, see message #10 below:

10-09-2023 @ 9:41pm

  1. I've added a schematic, see message #11 below:

10-11-2023 @ 9:41am

  1. Arduino cook book arrived yesterday
  2. Purchased larger stepper motor
  3. Purchased 4A motor driver

10-11-2023 @ 9:52am

  1. Iā€™m working on a flowchart of how the system should work when finished to better help the readers of my overly long posts.

10-11-2023 @2:59pm

  1. Updated project materials list above, see bold items.

I assume yuve done tests with the motor to determine the speeds and torque you need are possible with your belt/reduction arrangement.

Are you committed to a stepper, or would a geared DC motor be more approprate ?

You donā€™t mention reversing direction, so Iā€™m guessing the motor runs forward until it completes a full cycle to ā€˜get homeā€™.

I have determined the NEMA 17 is adequate but would probably step up to the next size when the project is done so that I could have higher speed because I could use less of a gear reduction.

A geared DC motor would work great and ultimately have a better torque advantage (and cost) than a NEMA stepper and has been a considered but my experience with geared DC motors is that they don't stop very fast and change where they stop depending on the load. If I could find a predictable DC gear motor I'd probably go that route. Also, I'm hoping the motor will be fairly quiet in the end and it seems most of the gear motors that are quiet and last for very long cost a fortune. If you have ideas, please feel free to let me know! A motor that is too big, but still within the appropriate price range would be just fine.

The motor will need to continue in a "forward" direction until it reaches "home" backing up will cause issues in the end design.

I recommend you spend some time with the Arduino Cookbook and also follow some tutorials on basic electronics and the arduino.

This makes no sense to me. The whole reason for a cog belt is the matching pullies. One on the stepper and one on what is being rotated. With proper tension, likely a spring loaded pulley, the belt would never slip. Time for a picture or better, a drawing of your project.

I haven't had much time to go through Arduino for beginners, etc. but I'm dedicating every moment I have when I'm not working on daylight projects to learning more. I have ordered the Arduino Cookbook and will read through it when it arrives.

I have also played around with the Arduino and the different shields I have to learn more about them and how to manipulate them to perform various tasks.

As much as I'm not a fan of Scratch, it would be really easy for me to make a program like this run on that code style of IF this THEN that. pretty much I can visualize the code in a mechanical way and it's really nothing more than a bunch of constraints:
IF home button circuit open AND pedal released THEN stop, IF home button circuit closed AND pedal released THEN continue moving, REPEAT UNTIL: IF home button circuit open AND pedal released THEN stop and so on...

NOTE: Above, I have written if circuit open it can stop, the reason for this is if a wire gets injured or a switch fails, it will stop rather than continue running until I can frantically unplug the system. Basically incorporating in some "safety" features.

EDIT
10-10-2023 @ 09:45pm

  1. Arduino Cookbook arrived today. WOW, thatā€™s a lot of information. Iā€™ll be reading through the Cookbook for the next few monthsā€¦ also it immediately told me I need a bigger stepper motor driver because my motor is 2.8A, not accounting for the stall current. I got a 4A driver because I wonā€™t ever be pulling the full load of the motor. (Upsized the motor so it would be able to run high speeds with moderate torque over a long service life.)

10-11-2023 @ 12:01am

  1. I have discovered a scratch-based program for Arduino, S4A. It looks like a great idea but Iā€™m going to work through the code in the Cookbook and go from there. Thereā€™s info on hooking up the stepper to my controller to the UNO. Thereā€™s info for switches and lights, I havenā€™t noticed info for variables (foot pedal) driving actions (stepper speed/go home) at any time in a void loop yet but will read it through. Thank you for the advice!


Here's a picture, the cut in the ring is for entry/escape of the product so a timing belt running around its circumference wouldn't work, this is why the belt will be driving the ring on its non-cogged surface. I could definitely drive a gear set but this would add several additional parts that would wear over time and render the project unusable until repaired if it were to skip a tooth. I could also use a double-sided timing belt to prevent mis-timing and that would work but then I'd have to cut the ring with the proper teeth and I'd be concerned about the teeth lining up each time the opening came around.

Maybe I've over-thunk this project but, mechanically, it's really quite basic and is a very tiny electrical project compared to what I'm used to, it just involves code, which I'm just beginning to learn.

EDIT:
10-09-2023 @ 12:16am

  1. If I used a gear set I could have 2 driving gears so there would always be at least one gear driving the ring at all times so it couldnā€™t skip alignment.

How about a rubber tired wheel on the stepper pressing against the OD of the ring?

1 Like

My initial thought when I read your comment was ā€œwhy not, seems like a great idea!ā€ Then I remembered that the ring has the opening so it would lose contact every time the opening came around, that was the reason for the belt, which I now realize would also require a tensioner.

Iā€™ll upload a more complete image tomorrow to help better show the project. I wonder if I can upload a video snippet of a Fusion 360 motion rendering?

Here's some complete pictures.



Machine Wiring Schematic.pdf (8.8 KB)

Here's a schematic of what I think I need to wire up. The stepper isn't included because I don't see a way to add one into the Tinkercad circuit design.

If you drive with three drive gears that are spaced around the circle, then the open space is a non-problem as the remaining two gears will continue to drive. The design challenge is to drive three gears at the same speed.

Maybe 3 drive gears? The gears could run with a few gears between to keep time. I wonder how long 3D printed PLA gears would last? I could print a gear ring with an opening and as long as at least one gear was driving it at all times that would work. My original reason for not gears was mostly the ring having to be cut with teeth but a screw-on gear ring would work excellent.

I wonder about the durability of 3D printed PLA gear teeth, Iā€™ve donā€™t a lot of 3D printing but only have ASA or PLA for a gear and havenā€™t made gears with them before for anything more than mock-ups.

OK, I have been reading through the Arduino Cookbook (3rd Edition).
I have decided I should build the project one step at a time. I have hooked up the stepper and the driver board as a starting point because if they don't work, nothing does. With it all hooked up, I've played around with some changes and have had some odd outcomes.

also, I found the Cookbook code examples for editions 1 and 2 on the O'reilly publication resource site but they don't have the 3rd Edition code.

Here's my current code (from the Cookbook edition 3)

const int dirPin   = 2;
const int stepPin  = 3;
const int enPin    = 4;

int speed = 100;
int steps = 0;
long last_step = millis();
long timeout = 5 * 1000;

void setup()
{
  pinMode(dirPin, OUTPUT);
  pinMode(stepPin, OUTPUT);
  pinMode(enPin, OUTPUT);
  Serial.begin(9600);
}

void loop()
{
  if (millis() > last_step + timeout)
  {
    digitalWrite(enPin,HIGH);
  }
  if (Serial.available())
  {
    char ch=Serial.read();
    if(isDigit(ch))
    {
      steps=steps*10+ch-'0';
    }
    else if(ch == '+')
    {step(steps);
    steps=0;
    }
    else if(ch=='-')
    {step(-steps);
    steps=0;
    }
    else if(ch=='s')
    {
      speed=steps;
      Serial.print("setting speed to "); Serial.println(steps);
      steps=0;
    }
  }
}
void step(int steps)
{
  int stepDelay=1000/speed;
  int stepsLeft;

  digitalWrite(enPin,LOW);
  last_step=millis();

  if (steps < 0)
  {
    digitalWrite (dirPin, LOW);
    stepsLeft=steps;
  }
  if (steps<0)
  {
    digitalWrite(dirPin, LOW);
    stepsLeft=-steps;
  }
  while(stepsLeft>0)
  {
    digitalWrite(stepPin, HIGH);
    delayMicroseconds(1);
    digitalWrite(stepPin, LOW);
    delay(stepDelay);
    stepsLeft--;
  }
}

The stepper turns when given a command to turn a given number of steps through the serial monitor.
Here's an example: I type

10s

and the motor steps very slowly when I enter the command:

5+

but here's the catch, the motor always turns about 11 rotations.
If I type this:

1+

I receive 11 turns at the above commanded speed of "10"
If I type this:

30+

I receive 11 turns at the above commanded speed of "10"
If I type this:

150s

then

5+

I get 11 turns at the commanded speed of "150"
If I type this:

15-

I get 11 turns, (same direction as a "+" number) at the above commanded speed of "150"

What's going on?

I have the TB6600 Driver from amazon (link in first message) and have set the DIP switches to "1 micro-step, 200 pulses/revolution, current limit 2.0A" I have tried higher and lower current limits and the only difference it makes is how loud the motor is. If I change the pulse/revolution count to 800, I get about 2.75 revolutions per command I send the Arduino (1/4 of 11 rotations)

I've tried changing the different numbers in the code I have included but haven't gotten any changes (other than the int speed does apply that number as the speed when the reset button is pushed).

All my grounds are linked.

  • DIR(-) [DRIVER]
  • PUL(-) [DRIVER]
  • ENA(-) [DRIVER]
  • GND [DRIVER]
  • GND [ARDUINO]
  • GND [ARDUINO]
  • GND [ARDUINO]
  • GROUND from 12V supply

Black(+)/Green(-) is Phase B
Blue(+)/Red(-) is Phase A
Driver board is supplied by a DC 12V, 3A power supply

  • 12V(+) goes to VCC(+) pin on the high voltage side of the driver board
    Arduino is powered via USB.
    PIN 2 is hooked to DIR(+)
    PIN 3 is hooked to PUL(+)
    PIN 4 is hooked to ENA(+)

What's Wrong?

Hereā€™s the code from the book and a few images of how itā€™s hooked up so you can see it for yourself.








What is wrong? Nothing is wrong! The program is doing exactly what it is written to do. The speed of stepping is slow because of the long delay after each step.

The problem I have isnā€™t speed though. I can change the speed by entering a new ā€œ[XXX]sā€ value.

What I canā€™t seem to control is the number of steps the motor takes. It always seems to make the same number of steps, wether I tell it to make 1 step or 10,000 steps.
If I type 1+ it should make one twitch and stop there but it turns 11 times without explanation. Same thing no matter how many steps I want.

My code was matching the Cookbook when I started but then I changed some numbers trying to isolate the problem, thatā€™s why itā€™s a little different from the pictures I posted but I never found a way to affect this. What really puzzles me is that it has chosen 11 turns, why 11? I see nothing that indicates it should choose 11, why doesnā€™t it randomly choose 5 turns or 7 turns? Thereā€™s no ā€œ11ā€ in my code and I donā€™t see any multiple of 11 either. This is where Iā€™m really stumped.

The program acts like thereā€™s a predetermined step count programmed to ignore my number and just do itā€™s predetermined operation (11 turns) any time I give it a number with a +. In theory I should have to tell it to move 2,200 steps to get 11 turns but Iā€™ve never told it to do thatā€¦

  • if foot pedal controls speed, what controls direction?
  • what should happen if the foot is off the pedal: stop, return home
  • presumably the foot pedal does start the motor until partially pressed
  • what would cause the motor to return "home"?
  • when returning home (in that direction) the microswitch would stop the motor and reset it's position. the motor would be allowed to move in the opposite direction, away from the switch

look this over
separates entering a multidigit value from the variable it sets and operation (e.g. step())

input might look like this

20S+++++++++++++++++++++++s
const int dirPin   = 2;
const int stepPin  = 3;
const int enPin    = 4;

int val;
int steps;
int speed = 5;

// -----------------------------------------------------------------------------
void loop ()
{
    if (Serial.available()) {
        char ch=Serial.read ();

        if (isDigit(ch))
            val = val*10 + ch-'0';

        else if (ch == '+')
            steps++;

        else if (ch=='-')
            steps--;

        else if (ch=='S')
            speed = val;

        else if (ch=='s')  {
            step (steps);
            steps = 0;
        }
    }
}

// -----------------------------------------------------------------------------
void step (int steps)
{
    Serial.print ("step: ");
    Serial.println (steps);

    int stepDelay = 1000 / speed;

    digitalWrite (dirPin, LOW);
    if (steps < 0) {
        steps = -steps;
        digitalWrite (dirPin, HIGH);
    }

    while (steps--) {
        digitalWrite (stepPin, HIGH);
        delay        (stepDelay/2);
        digitalWrite (stepPin, LOW);
        delay        (stepDelay/2);
    }
}

// -----------------------------------------------------------------------------
void setup ()
{
    pinMode (dirPin,  OUTPUT);
    pinMode (stepPin, OUTPUT);
    pinMode (enPin,   OUTPUT);

    digitalWrite (dirPin, LOW);
    digitalWrite (stepPin,LOW);
    digitalWrite (enPin,  LOW);       // enabled?

    Serial.begin (9600);
}

If you are using a limit switch for home position, I don't see any need for step / pulse counting, only speed control. What maximum speed are you looking for?

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.