Nano and AccelStepper

HI Trying to get a small simple project to go using AccelStepper. (a bit quiet on AccelStepper group at the moment)
Have sketch with 5 positions for the stepper to go to, all equal distance apart and all at the same speed.
Change will occur with a button press to select a position (code all done for setting new position and the variaqble new_pos will hold this, changes each time a button pressed. In the meantime I want to change the number in the variable on the monitor each time and rerun the code.
The current position will always be the position at which it is at the moment. (not 0 as some commands state)
What are the minimum commands I can use to achieve this. The only command is when the button pressed it sends data of which button and it goes to that pos.
Stepper in position 4 and then
If button 3 pressed goes to position 3 from pos 4
then if button 5 pressed goes to pos 5 from pos3 etc

AccelMoveTest.ino (795 Bytes)

Please post the code here using code tags when you do

Does it have to be AccelStepper?
You could use my MobaTools lib ( can be installed by means of library manager ) .

/*  Position a stepper according to buttonpresses
 *  The stepper is connected by means of step/dir driver
 *  The buttons are connected between pins and GND ( using internal pullups )
 */
#include <MobaTools.h>

const int stepRev = 200;    // steps per revolution
// adjust stepper pins to your needs
const byte dirPin = 5;
const byte stepPin = 6;
const byte enablePin = 7;
// create stepper object
MoToStepper myStepper( stepRev, STEPDIR );

// create button objects
const byte buttonPins[] = { A0,A1,A2,A3,A4 };                   // adjust pins to your needs
const long stepperPositions[] = { 500, 1000, 1500, 2000, 2500 };// must be same number of elements as buttonPins
const byte buttonCnt = sizeof(buttonPins);                      // number of buttons/positions

MoToButtons myButtons( buttonPins, buttonCnt, 20, 500 );

void setup() {
  myStepper.attach(stepPin, dirPin);
  myStepper.setSpeedSteps( 10000 );                 // = 1000 Steps per second
  myStepper.setRampLen( 50 );                       // 50 steps to achive set speed
  //myStepper.attachEnable( enablePin, 100, LOW );   // if you want to switch off power when stepper reached position
  // a homing procedure may be needed here
}

void loop() {
  myButtons.processButtons();                // Check buttonstates
  for( byte pos= 0; pos<buttonCnt; pos++ ) {
    if ( myButtons.pressed(pos) ) {
      // position stepper according to pressed button
      myStepper.writeSteps( stepperPositions[pos] );
    }
  }
}

Speed and positions could also be defined as rpm and angle if desired.

I think I will include that as an example in my lib :wink:

Hi MicroBahner

Wow, that looks great. Just what I want. I will try out later today. Thankyou for that.
Have not come across your library before.
Will keep you informed.
Lots of thanks from here in New Zealand. Luckily no covid problems here presently. No lockdowns either.
Charles Harris

Hi MicroBahner

Forgot to mention and I think you have guessed what it is for. A model railway transfer table that travels sideways. Not the rotary turntable.

Hi MicroBahner
Would you mind an example of :

A soft led that turns on or off (for lights in a model building etc) activated by another button.

with your example code above what do I call using ' println' to have the current position (say 4) to show on the monitor, and also the new position that has been selected (say 3). These would change after each button press. Sometime in your examples file astandard LCD that shows present position. 2 line ( say "Current Position is and next line Track 4
Do you have a web page. Catch me on swchuck@gmail.com
Thanks

Charles

Hi Charles,

Sounds great :sunglasses: . But I think you'll need a reference point to start from ( the homing procedure I already mentioned in the sketch ).

Should not be a big problem by adding some additional buttons to the array.

myButtons.pressed is true only once when you press the button. You could just add a Serial.print in the body of the if block. It will execute only once to print the position when you press the button. Something like

    if ( myButtons.pressed(pos) ) {
      // Button was pressed, move stepper to the according position
      Serial.print("Move from "); Serial.print(lastPos); Serial.print(" to "); Serial.println(pos);
      myStepper.write( stepperPositions[pos] );
      lastPos = pos;
    }

Do you already have one? I would prefer one with I2C interface because it needs only 2 pins.

Unfortunately not.

Greetings to the other end of the world :slight_smile:
Franz-Peter

Hi Franz
Thanks for your great info. I am 77 yrs old and a bit slow on the learning. Sorry for the many questions.

for a homing code do I use command move or moveTo or something else, in the setup code for the stepper to go back to 0 position at startup. myStepper.move(0) ??? (do I refer to buttons 0, 1, 2, 3,4 ?

and for a complete stop (in an emergency), use another button, and code myStepper.stop() or myStepper.rotate() which is best?

With the moving table with loco on do I need to have a micro switch sensor at each end of travel to stop the motor over running and use the stop code above?

Your comments are much appreciated.

Charles

Hi Charles,

Ok, I'm a few years younger, but we are in the same range :wink:

You need a limit switch at one end of the movement range. In setup() you can use the rotate(1) or rotate(-1) method to move in the direction of the switch. The sign depends on the correct direction (towards the switch). When the limit switch turns on, stop with rotate(0). Then slowly go back a few steps ( with doSteps() ) until the switch turns off again. This is now your reference point ( setZero() ). All step positions are counted from this position. If you tell the stepper 'writeSteps(10000)', it will go to the position that is 10000 steps away from the reference point - no matter where it starts from at that moment.

Something like this:

  mystepper.setSpeedSteps(5000,50);   // Set speed and ramplength
  mystepper.rotate(-1);               // drection must be towards the end switch
  while ( digitalRead( EndSwitchPin ) == LOW );  // HIGH/LOW according to your switch
  // endwitch reached
  myStepper.rotate(0);
  // go slowly back until it switches again.
  mystepper.setSpeedSteps(200,50);   // slowly
  myStepper.doSteps( 200 );         // must be sufficent, to reach the switching point again
  while( digitalRead( EndSwitchPin == HIGH );
  myStepper.stop()
  myStepper.setZero();            // This is now the reference point

Since I'm not at home for the next days, I can't test it. But it should show the principle.

In case of emergency stop() ist the best, because it stops the stepper immediately. With rotate(0) it will decelerate according to the set ramplength. So it may need a little time unitl it stops.

Once the referencepoint is set with a switch at one end, the motor should never over run at the other end ( if you set the step positions correctly for all stop points ).

Franz-Peter

Hi Franz

Thanks for info. Processing all the info now. Great. Have a good break for a few days.

Charles

Hi Just an update on my project. Code below. Franz would you mind checking the code. As it is at the moment it compiles ok. I will introduce the home code after the first part working ok.
Do you have a sketch that just checks that motor working ok, run the motor fwd and reverse etc. This so I can check the wiring of motor etc before uploading the above sketch.The motor has 4 wires colors red, white, yellow, black (which is different to most motors) Are you able to confirm what pins they go to on the A4988.
Hopefully the main code is quite ok!
Thankyou
Charles

No code on this thread I can find to load code direct into message.

MobaVs2.ino (4.5 KB)

Hi Charles,

Press 'ctrl-T' to format your code Then right click into the code window of the IDE and select 'Copy for forum'. Then insert into your post.

The lib contains an example 'minimumStepper'. Its just to get the stepper turning, nothing else. So you can check if it works. If you change 'rotate(1) to rotate(-1) in the sketch it should turn the other way around.