Control direction of stepper motor using toggle switch

Hello I am trying to control the direction and speed of a stepper motor using the following program. The speed counter seems to work, unfortunately i am not able to control the direction. Is my approach wrong?


#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <ezButton.h>
#include <AccelStepper.h>


// Set the LCD address to 0x27 for a 16 chars and 2 line display
LiquidCrystal_I2C lcd(0x27, 16, 2);


ezButton inc (9);
ezButton dec (10);

ezButton cw (6);
ezButton ccw(7);

int cnt = 0;
int incPrev, decPrev, speedPrev, val1, val2;

// Define stepper motor connections and steps per revolution:
const int dirPin = 2;
const int stepPin = 3;

AccelStepper myStepper(1, stepPin, dirPin);
//#define stepsPerRevolution 10
long speed;

void setup()
{
  //lcd
  lcd.begin(16, 2);
  lcd.backlight();

  pinMode(stepPin, OUTPUT);
  pinMode(dirPin, OUTPUT);

  myStepper.setMaxSpeed(10000);

  Serial.begin(115200);
  delay(2000);
  digitalWrite(dirPin, HIGH);
}

void loop()
{
  inc.loop();
  dec.loop();
  cw.loop();
  ccw.loop();

  updatecnt();

  myStepper.runSpeed();
}
void updatecnt ()
{
  bool update = false;  // no need to update speed

  if (inc.isPressed() && cnt < 10) {
    cnt++;
    update = true;
  }
  else if (dec.isPressed() && cnt > 0) {
    cnt--;
    update = true;
  }

  if (( update == true )  &&  (cw.isPressed() )){
    long speed = 200 * cnt;

    Serial.print("New speed = ");
    Serial.println(speed);

    myStepper.setSpeed(speed);
    lcd.clear();
    lcd.print("RPM = ");
    lcd.print(cnt);
}
    else if (( update == true )  &&  (ccw.isPressed() ))
{
    long speed = 200 * cnt;

    Serial.print("New speed = ");
    Serial.println(speed);

    myStepper.setSpeed(-speed);
    lcd.clear();
    lcd.print("RPM = ");
    lcd.print(cnt);
  }
}

Yes, you have a logical error I think.

Fix updatecnt(). You never have a chance to act on the flag you set, as you clear it right away next time.

This makes update stick around between calls to updatecnt():


void updatecnt ()
{
  static bool update;  // need to update?

Then, both places when you test update, clear the flag if you used it:

    else if (( update == true )  &&  (ccw.isPressed() ))
{
       update = false;      // ok, took care of the update necessity

That way, INC and DEC set the flag, and CCW and CW do something becuase, and clear it.

Sry for the snippets, I did test this but haven't gottenthe stepper motor wired yet. I may have time before my beach buddy calls.

But that update is def not helping you recognize and handle the CW and CCW action buttons.

HTH

a7

See the slightly modified code here:


Wokwi_badge Step Direction Sketch


You will see there are some problems still. But at least it can be made to do something plasuible.

a7

OK, never mind, finally I notice you want to use a toggle switch.

In that case I don't think ezButton is helping you.

Can you just describe in words what kind of buttons and switches, and how they should affect the display and the action of the motor?

Is the toggle switch SPDT? Does it have a center off position?

How are the switches and buttons wired?

I assume the speed should change with the button presses inc and dec right away.

a7

If using a toggle switch for direction, why bother using any code for direction change...?

@christysunny - Here is a "pushbutton" simulation that randomly picks a speed and changes directions.

@alto777 Thank you so much. You are really helpful.

I have modified the program and added a couple more switches to enable more control. Here is the link to it.

But Still, this is not working the way i want it and i couldn't resolve the issues.

There are few issues here:

  • The toggle switch doesn't change direction instantaneously when i switch it. I need to press the inc/dec button to make it work.
    -I added another toggle switch to control the operation mode; continuous rotation vs motor rotate when switch is pressed. But this doesn't seem to work.

I am beginner when it comes to arduino, so any help would be appreciated.

  • The switch is a two position switch, no center off position.
  • Yes, the speed must change with the press of the inc?dec button right away.

I'm in transit, looking through the little window, and the wokwi doesn't work very well that small.

If you call

    MyStepper.runSpeed();

in the loop, and you have not set the speed to 0, the stepper will run.

Maybe you should spend some time figuring out what and how the stepper motor library is helping you.

At this point it is getting complicated enough so I would suggest restructuring the code.

Use the IPO model.

Make three sections in the loop:

Input: In the first, read all buttons and switches.

Process: Next, use the condition of the switches and buttons, and what you are currently doing with the motor, to decide what to do next.

Output: Lastly, tell the motor what to do.

Rinse and repeat, as is said.

I'll look at the wokwi when I get to the lab.

a7

@christysunny OK, look at this

Wokwi_badge Step Direction Sketch IPO


It does not do all and what you want. It is just a beginning of the restructuring. If you read through the code, you can see what I am talking about. I tried to put //... where I made changes.

Note: ezButton needs

  manual.setDebounceTime(25);

the denounce time set for every button that is EZ. ALso note, several of your switches and buttons do not need to be EZ. Just read them and use the logic value as I show.

Going under the umbrella just now. See if that framework makes it easier to implement your advnaced control features.

HTH

a7

@alto777 Thank you again.

I still have a small issue. "presstorotate" button doesn't seem to work. so i added these to lines to the your sketch. Still no success.

 if (manual.isReleased() && presstorotate.isPressed()) running = true;
  if (presstorotate.isReleased()) running = false;

The sketch seems to work correctly when i added this.

 if (presstorotate.isPressed()) running = true;
  if (presstorotate.isReleased()) running = false;

What could be reason??

Do you have an understanding of how ezButtons function?

I'm not a fan of library code, especially button code. I have a minimal grip on what ezButton can and cannot do for you. I may have come to some inaccuracies, I suggest that you familiar ize yourself with the examples using ezButton that come with the library. I hope there are examples.

But I the below is close enough:

If all you want to check is the level of a digital input, just use digitalRead() on the pin. I used digitalRead() on one pin to dictate the motor direction.

If you want to take action when a button gets pressed, test buttonWhatever.isPressed().

isPressed returns true once each time you press the button.

I used isPressed() to turn on the motor.

If you want to take action when a button gets released, test buttonWhatever.isReleased().

isReleased returns true once each time you let off the button.

I used isReleaswd() to turn off the morot.

You might see I could have just used the level… many choices.

I think if you keep all this in mind and carefully read the code, you will be able to get the other switches and buttons working.

Not where I can he;p,otherwise just now.

a7

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