Model Railroad Turntable Project

151 views
Skip to first unread message

Anthony Kochevar

unread,
Sep 14, 2022, 12:33:19 PM9/14/22
to accelstepper
New member here.  Wanting to use this library for my turntable project.  I've been going over examples and have been reading the lost manual.  I'm looking for tips and advice on doing the following.

Setup:
-Turntable will be both indexed and allow for manual movement.  A momentary toggle switch DPDT with center off (springs to center off when released) will be used and a 10k potentiometer for speed adjustment.

-When the toggle is thrown and released for less than a second ether way, the turntable will capture the pots speed and move it to the next indexed position set in the code in the proper direction.  Accel and Deceleration with be used.  The speed will not be adjustable during movement until it stops at the indexed position

-When the toggle is thrown and held for over a second the turntable will move in that direction.  Accel and Decel, will not be used and the speed will be adjustable as the turntable moves on the fly.  This I'm not sure how to accomplish this with this library from what I've read so far.

Just wondering if this library can do this and some pointers on how.

Any advice would be helpful and thanks in advance.




Seth Perkins

unread,
Sep 14, 2022, 1:21:20 PM9/14/22
to accels...@googlegroups.com
This sounds like a cool project and you should be able to accomplish it using only the accel stepper library and the standard arduino library.
For your hardware setup I would pull up the IO lines with a resistor to VCC (Probably 5V with arduino UNO) and GND through your DPDT switch. Either IO pin will read 0 when the toggle is thrown either direction. You can omit the external resistors if you configure your pin as input pullup resistors like this for example on pin 2. 

in setup:

int SW1_INPUT = 2; // Set 2 and 3 as GPIOS for switch.
int SW2_INPUT = 3;

pinMode(SW1_INPUT , INPUT_PULLUP);
pinMode(SW2_INPUT , INPUT_PULLUP);

in loop:
read the pins using

if(!digitalRead(SW1_INPUT))    // the '!' symbol is negating so this reads as" if(digitalRead(SW1_INPUT) == 0) meaning the condition is satisfied when the pin at 0v
{
  do stuff here
}

To read potentiometer use

int reading = analogRead(pot_output); //You can get a value from the adc for the potentiometer reading. 

The code will be slightly tricky because you cannot use delays for timing. Let me know if this is too much or you need more help with the hold vs toggle functionality of the switch.
image.png

--
You received this message because you are subscribed to the Google Groups "accelstepper" group.
To unsubscribe from this group and stop receiving emails from it, send an email to accelstepper...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/accelstepper/129fef40-b3fc-4e1e-953b-353620a3afcbn%40googlegroups.com.


--
Seth Perkins
928-607-8167
Planet Rider Motors

je...@siddall.name

unread,
Sep 14, 2022, 2:05:51 PM9/14/22
to accelstepper
Interesting project.

I don't have much to add except to say you should probably use accel/decel for everything.  Most stepper setups can't go from stopped to full speed without some accel without problems because... physics.

With testing you can figure out what the maximum accel your steppers can support and then use that for manual mode.  The rates could be pretty quick so it might not seem like it is using accel/decel to the user.

Doing short and long presses is going to require timers, which will add some (or a lot) of complexity.  An easier solution might be to have two switches: manual/automatic mode and forward/reverse.  Each could be SPST so would be cheaper than a momentary DT.

Good luck!

Neil Watson

unread,
Sep 14, 2022, 5:46:48 PM9/14/22
to accels...@googlegroups.com
Hi Anthony. What scale are you modelling? I'm in the process of developing a TT myself. I've attempting 1 for OO9 and another for N. I'm going down the route of having fixed exit/entry points rather than manually turning but now might consider manual control.

Jim Larson

unread,
Sep 14, 2022, 6:55:25 PM9/14/22
to accelstepper
An interesting project, Anthony! Sounds very doable, but you'll need to handle some details.
My first suggestion is to do this in stages. Get the turntable to move, then move to indexed positions, then read the pot for variable speed, etc. Don't try to get it all working at once. Building on working code is much easier than trying to debug a huge program.

Now for some details. First, how will indexing be done? Will there be switches at each stop, or will you just know the number of steps to move? If the latter, how will you know the starting location/
Second, will the toggle be held for the entire manual move? If not, how will the move be ended?
Third, do you expect to be able to trigger a move while a move is in process? Not allowing this will make your life easier. I suggest that approach unless you just can't live with it.

And some suggestions: The elapsedMillis library can probably provide the capability for timing that you will need.
Designing a state machine in your loop() should give you a good structure for your program.

You will find some discussion and example programs that may be helpful here:

gjgsm...@gmail.com

unread,
Sep 14, 2022, 8:46:59 PM9/14/22
to accels...@googlegroups.com

Another solution is to use a 12bit encoder which will enable very accurate positioning (4095 positions per revolution). This is a simple solution which means you don’t need any switches as the encoder will remember its zero starting point even with power off. Also, if the stepper does miss a step during travel, it will still arrive at your index/target points accurately every time. For the initial setup of your stepper, the encoder is very easy to zero, so once you have moved the stepper to the start position you zero the encoder and then set your accelstepper targets (you only need to do this once) and then run your program. The stepper can be in any position before power on and it will go to any pre-determined position on run, using the encoder.

 

The encoder I have used extensively is a commonly available CUI capacitance type encoder, excellent value at around USD50. It uses SPI communication for which I can assist with some simple code to get it all working if you like.

--

Anthony Kochevar

unread,
Sep 15, 2022, 4:29:13 AM9/15/22
to accelstepper
Thanks everyone for the suggestions.  This isn't my first Arduino project, but it is my first time using the AccelStepper library and I will keep the 12bit hardware in mind if what I'm planning on using doesn't work out.  Here is a bit more info that might help what I'm trying to wrap my head around.

I know how to read the switches and pot inputs in the code, no issues there.  The reason for having both indexed and manual operation is the user will use a slow speed via the pots input to move the turntable into an indexed position they want manually.  Accel and decel will be turned off for manual control so the user doesn't overshoot the positioning he needs when the switch is released. He will need to have the pots set really low and speed really low for this fine adjustment.  The Arduino will then output this position when stopped to serial monitor.  The user will make note of the position(s), as many as he wants, and input these in and array in the code.  The user can then reupload the code with his tailored positions to the Arduino.  The user can then flip the switch and release in either direction and it with use Accel and Decel and move to that position.  The user can still use manual control and the pots to test and set Maxspeed in the code.  Another reason for indexing is to use the turntable with JMRI via the CMRI interface and have the turntable remotely controlled and not use the switch if the user chooses.

I have sketches for doing much of this,  just need to combine them and again this isn't my first railroad Arduino project.  My main issue with this library is the manual control portion of the turntable.  From my reading the missing manual I'm not sure this library can have the stepper moving already non stop and have a speed adjustment implemented without it needing to stop first.  The Arduino stepper library can do this quite easily in its example sketch.  I'm looking for help for the code for using the manual control in this library so I can get Accel and decel for just the indexed portion.

Can I use both libraries in the same sketch?  Can I use the Accelstepper for the indexed portion and the standard library for the manual control portion in the same sketch without issue?


I basically want to do the following below from the standard stepper example but in this Accelstepper library and also disabling Accel and Decel  first so they can get an accurate index position reading for use in the indexed portion that will reenable and use Accel and Decel.   I'm not understanding exactly how to go about this with this Accelstepper library.

void loop() {
  // read the sensor value:
  int sensorReading = analogRead(A0); // Read Pots value
  // map it to a range from 0 to 100:
  int motorSpeed = map(sensorReading, 0, 1023, 0, 100);
  // set the motor speed:
  if (motorSpeed > 5) {
    myStepper.setSpeed(motorSpeed);
    // step 1/100 of a revolution:
    myStepper.step(stepsPerRevolution / 100);
  }
}

Anthony Kochevar

unread,
Sep 15, 2022, 8:58:52 AM9/15/22
to accelstepper
Sorry, forgot to mention this is for a 5 inch N scale turntable I'm designing and 3D printing.

Jim Larson

unread,
Sep 15, 2022, 5:01:24 PM9/15/22
to accelstepper
For an example of using a pot to control a motor's speed, have a look at the file UnoAccelStepper_speedControl.ino found in the Files section of the link I cited above. You may find the discussion in Step 3 of the Instructions in that document helpful as well. Further, the last few steps in the Instructions discuss the use of state machines which could work well for your application.

        -jim

Anthony Kochevar

unread,
Sep 15, 2022, 5:46:33 PM9/15/22
to accelstepper
Awesome tips Jim!  Hadn't got to all the examples in the missing manual yet but that looks like what I need.  Also, thanks for the elapsedMillis info.  I'll have to give it a try as well.

Anthony Kochevar

unread,
Sep 17, 2022, 6:05:24 AM9/17/22
to accelstepper
I got the manual control of the turntable working good.  The index portion is proving to be a challenge.  How do you keep track of an accurate current position in a variable when using this library?  I'm using a 28BYJ-48 stepper and basic board.  In the standard stepper library this has 200 steps per revolution.  Using the currentPosition call in Accell stepper yields much bugger or sometimes negative numbers.  I also found this:

But I'm not sure what it is doing or how to use it in my sketch.


Jim Larson

unread,
Sep 17, 2022, 6:23:16 PM9/17/22
to accelstepper
This is one of those questions that seems like it ought to be easy, but isn't. You have already discovered that AcceslStepper only knows about steps. Two things must be considered:
- How do you know or determine position zero? That's the reference for all movement and when you need absolute position, you must determine this. A switch of some sort is usually used.
- What do you do about wrap-around? That is, if you allow movement beyond 360 degrees (I assume can translate degrees to steps in your system), how do you keep track of that and how do you then return to the zero position? One approach is to only allow absolute movement (using moveTo()) and to translate angles to steps for that command. Then you can create a function called moveAngle() which limits movement to 360 degrees max, does the translation to steps, and calls moveTo(). The next problem you will discover is that a movement from 355degrees to 5 degrees will want to go the long way (350 degrees), since the short way (10 degrees) will not be allowed. There are a few ways to handle that.

Also, I would not use the code that you reference. There are a couple of obvious problems with it. I can discuss those if you would like.

Congratulations on your progress so far!

           -jim
Reply all
Reply to author
Forward
0 new messages