Tips for Arduno software for Rotary Table Controllers

Home Model Engine Machinist Forum

Help Support Home Model Engine Machinist Forum:

This site may earn a commission from merchant affiliate links, including eBay, Amazon, and others.
Harry, I did think about backlash but decided that if you only travelled in one direction which is the usual case there was nothing to worry about compensating for.

So just thinking out loud, Backlash only becomes an issue when you change direction. I think you'd have a variable that said how many steps or degrees of backlash. You should be able to include this in the global setup structure and modify the setup input screen so you could edit it. Then just mantain a global flag that said direction had changed and reset it after the first movement. That way if the flag was set, you'd just add the backlash compensation to the number of steps to move (and rest the flag at the end). I think it would be pretty simple to incorporate.
 
@rodw

I understand this project is somewhat historical so probably well out of mind by now
but if you had any suggestion re the best place to start inserting backlash compensation would be appreciated.
I haven't looked at the code but somewhere in there I would expect to find a +ve/-ve or boolean value to define the direction of the next rotation.
It would only be necessary to add a statement that does this on completion of the rotation:

If direction negative, move -10 steps and then move +10 steps

The number of steps will depend on the measured backlash etc.
 
I can see a few applications where keeping track of rotation may be useful but, I think that if you have more backlash in your rotary table than you can live with tolerance wise , this won't fix it. The stepper will be backlash free and counts very well so it will be where it is supposed to be regardless of direction. The mechanical backlash in the rotary table is the issue and as soon as your tool hits the work it will move the work/table regardless of how accurately it was positioned.

What is really needed is a way to automatically apply a brake to the table after the move and release it before the next move. This would solve most backlash induced issues.

We almost always go in one direction so the backlash wouldn't be a problem and for those few occasions you do have to back up , adding some code to backup a little further and then come to position in the right direction would be easy.

Scott
 
Dazz, yes, there is a direction flag that is 1 for one way and 0r the other (globals.DirPin). Backlash only bites when the direction changes. There is a function called GoDivide() that responds to direction buttons and sets the distance to move.

So maybe something like this (one direction only shown)
Code:
while(event != LCD_BUTTON_SELECT){
      event = lcd.getButton();
      switch(event){
        case LCD_BUTTON_LEFT:
          flag++;
          thisDiv--;
          divLeftOver -= remainder;
          if(thisDiv < 1)
            thisDiv = divisions;
          if(globals.DirPin != ANTICLOCKWISE) // do we need to add backlash?
                 backlashsteps = global.backlash;
          else
                 backlashsteps = 0;
          digitalWrite( globals.DirPin, ANTICLOCKWISE );
          break;
        case LCD_BUTTON_RIGHT:


then later:

Code:
SetSteps((stepsPerDiv + adjustSteps + backlashsteps) * 2, 1);

Note this code might be a bit different to what is presented to make sure there are no missing steps. Details and code are in this thread so start with the GoDivide() function shown there:
https://www.homemodelenginemachinist.com/threads/interrupt-driven-rotary-table-controller.25091/
 
Thankyou for the swift and multiple responses,



Harry, I did think about backlash but decided that if you only travelled in one direction which is the usual case there was nothing to worry about compensating for.

So just thinking out loud, Backlash only becomes an issue when you change direction. I think you'd have a variable that said how many steps or degrees of backlash. You should be able to include this in the global setup structure and modify the setup input screen so you could edit it. Then just mantain a global flag that said direction had changed and reset it after the first movement. That way if the flag was set, you'd just add the backlash compensation to the number of steps to move (and rest the flag at the end). I think it would be pretty simple to incorporate.

So if I understand right what you suggest, is in a change of direction adding the step count that corresponds to the backlash present and so accounting for it.
My preference however is more to imitate what one tends to do manually, which is to always approach the mark
from one direction only(sloppy lathe cross slide comes to mind)
This will require either backing off , or deliberately overshooting the mark by some amount and then approach from the same direction in all cases as Scott describes above.
I do have pneumatic locks on this table by the way and the use is for multi axis positioning/indexing in a CNC mill.

What really intrigues me however is potential use as an automated downfeed in a surface grinder I am rebuilding.
In this case 1 micron is a measurable and settable amount of travel, whereas the total backlash between the handwheel and the wheel head is in the order of 5deg of handwheel movement(5micron). This requires a very consistent technique in setting the height. There are other issues to deal with also such as wheel dressingand its effect on position but that's for another time.

Again thanks for your thoughts and I will carry on from here

Cheers
Harry
 
Crossed posts ,
will look at this carefully
Harry

Dazz, yes, there is a direction flag that is 1 for one way and 0r the other (globals.DirPin). Backlash only bites when the direction changes. There is a function called GoDivide() that responds to direction buttons and sets the distance to move.

So maybe something like this (one direction only shown)
Code:
while(event != LCD_BUTTON_SELECT){
      event = lcd.getButton();
      switch(event){
        case LCD_BUTTON_LEFT:
          flag++;
          thisDiv--;
          divLeftOver -= remainder;
          if(thisDiv < 1)
            thisDiv = divisions;
          if(globals.DirPin != ANTICLOCKWISE) // do we need to add backlash?
                 backlashsteps = global.backlash;
          else
                 backlashsteps = 0;
          digitalWrite( globals.DirPin, ANTICLOCKWISE );
          break;
        case LCD_BUTTON_RIGHT:


then later:

Code:
SetSteps((stepsPerDiv + adjustSteps + backlashsteps) * 2, 1);

Note this code might be a bit different to what is presented to make sure there are no missing steps. Details and code are in this thread so start with the GoDivide() function shown there:
https://www.homemodelenginemachinist.com/threads/interrupt-driven-rotary-table-controller.25091/
 
Harry, What you have described is a one way movement so there will be no need to back off the current position when moving down. Backlash will not be an issue as stepper holding torque will keep the current position locked. Provided the stepper and gear train allow the stepper to give 1 micron resolution, you should not have any issues.

What you could consider is to use another output pin to activate your pneumatic lock. This could be done in the SetSteps procedure
Code:
void setSteps(long sSteps, int sWait)
{
int oldSpeed;

  rampSteps = (long)(((float)sSteps / 2.0));      // the number of on/off cycles
  startDelay =   HzToTimeDelay(globals.minStepperHz);        
  targetDelay =  HzToTimeDelay(globals.maxStepperHz);
  if(((startDelay-targetDelay) * globals.microSteps) < rampSteps) // Don't go faster than the max stepper speed
    rampSteps = ((startDelay-targetDelay) * globals.microSteps);
  startRampDown = rampSteps;           // Steps to start ramping down - steps count down so we start at a high #
  endRampUp = (sSteps - rampSteps);    // Steps to stop ramping up -- steps count down so we start at a high #
  oldSpeed = sDelay;                   // save the old speed
  sDelay = startDelay;                 // set starting delay
  Timer1.initialize(sDelay);           // set the interrupt timer
  stepcount = 0L;                      // Zero the step counter
  // Always Unlock solenoid here
  steps = sSteps;                      // GO for it
  if(sWait){
    while(steps){
      ;                                  // Wait until done
    }
    // lock solenoid here
  }
  sDelay = oldSpeed;
}

At this point, the move has been resolved to the number of stepper steps required to complete the move (sSteps).

This procedure takes a parameter to tell it if it should wait for the move to complete (dividing) or not (jogging)
The steps variable is what the interrupt routine counts down while moving the stepper motor. So you should always unlock the brake here in case the last move was a jog and lock it if sWait is true. You'd also need to lock the solenoid at start up and at the end of the rampDown() procedure so it was locked after any jogging moves. You'd probably need to add some dwell time to allow the solenoid to open and close so I would write a seperate procedure for that
Code:
int lockBrake(int lock)
// locks or unlocks brake depending on the state of the lock parameter
{
   if(lock){
      //lock the brake
   }
   else{
      //unlock the brake
   }
  // apply a dwell period so the solenoid has time to activate.
}
 
Last edited:
Crossed posts ,
will look at this carefully
Harry
Just be aware that the code needs to be duplicated for the CLOCKWISE direction under
Code:
case LCD_BUTTON_RIGHT
 
Quick question guy's , is there a general concensus on wich pins to use for step and dir ?

D3 D4 D5 D6 D7 D8 D9 ( pins 4 ...10) are sed by the shield if I understand corrctly .
D0 D1 ( pins 1 &2 ) are -sometimes- used for serial communication , so better to avoid also .

That would leave D2 and D10 for step and dir .

The reason I'm asking is that I'll be making a dedicated pcb for this with a nano and I would prefer
to get it right right away instead of having to cut traces .

Also , Rod , I tried to DL the genlookup.c program , but I'm getting page not found .
Offcourse I'll use thesame values as the original shield so it shouldn't be an issue .
But if you still have it somewhere , I'de like to take a look at it .

Big thx for this wonderfull project . It will keep me busy for the coming cold months .

What I like most about it is the possability to use it on multiple devices without having to recompile .

A feature I would add , if I had the skills to do it , is a home (proximity or optical or hall ) switch .
That would allow the device to home and then start from a known fixed position . Eg for a rotary table , one slot parallel to the x axis , or for a dividinghead one jaw parallel to the xy plane wich is handy when working with square or hex stock .
Just thinking out loud :) .
 
The Source code for the LCD library has moved in github
https://github.com/rweather/arduino-projects
genlookup is in a subfolder https://github.com/rweather/arduino-projects/tree/master/gen
And the LCD library is in this subfolder https://github.com/rweather/arduino-projects/tree/master/libraries/LCD

There are some good resources using prox switches with the arduino on youtube. Its not hard you just need the prox sensor in the correct voltage range and usually a pull up or pull down resistor depending on the sensor type PNP or NPN.

It does not matter much which pins to use, just if you use the serial pins, its best to turn off the stepper power as you get random movements from the serial port data when you update your sketch. I started with those pins but moved them later to do this(Which you can do in the config settings).

ScottM uses a prox sensor to trigger indexing under Gcode control
 
Back
Top