Rotary Table for a Millingmachine

Hello!

I follow a tutorial on a Rotary Table, to improve my electronic and programming skills a bit.
So far, i more or less can grasp the basics, but i got a problem with the multiplier of the source code provided by this tutorial:

https://www.cnczone.com/forums/arduino/215402-cnc.html

const int stp = 12; // connect pin 12 to step
const int dir = 13; // connect pin 13 to dir
const int StepsPerRotation = 204; // Set Steps per rotation of stepper 1 Revolution = 0.5°
const int TableRatio = 5; // ratio of rotary table
const int Multiplier = (StepsPerRotation * TableRatio)/360; // (204) original: 200*90=18000/360 = 50 
const int stepdelay = 1;
float Degrees = 0; // Degrees from Serial input
float ToMove = 0; // Steps to move
float bob = 0;
int cho = 0;

Now i got a caveat in my setup, that is because i need a stepper that packs a heavier punch, i got a 50:1 reduction gear to be able to use the stepper during milling, and not only to position the work.
So the hole thing is hooked up to a driver that is set at 200steps

So far, i figured out that for 204 Steps, i get 5° Rotation, that is, one full turn of the nut exactly.
But i can't figure out, the relationship between the TableRatio and the Steps to get it to calculate the correct amount of steps, say for moving the table 90°.

I am pretty much stuck and as much as i play around with the values it keeps getting worse :slight_smile:

some help would be much appreciated
thank you
Roger

Do You have any link to the actual rotating table You use?
Turning the handle 90 turns to make the table make one revolution is quit usual. Check Your table! If Your stepper uses 200 steps per revolution You need 200 * 90 == 18000 pulses per 360 degrees. Then 5 degrees need 5 * ( 18000 / 360 ) == 250 pulses.

as one full revolution of the handle result in 5°, that means to turn the table, i need 72 times to get one full revolution of the table.

so as i understand, i need to set the tableratio to 72.

stepsperrotation is actually 204, not 200 in my case, idk why but that's what the micrometer says :slight_smile:

204steps = 5° exactly
1 rotation of the handwheel = 5°

if i update the code, he turns a bit over 5°....

/*
4x4 matrix keypad amd a 20 x 4 LCD. Edit StepsPerRotation & TableRatio(# of turns for 360 degrees)
5/2/2015
*/

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>

const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'.','0','#','D'}
};

byte rowPINS[ROWS] = {11,10,9,8};
byte colPINS[COLS] = {7,6,5,4};

Keypad kpd = Keypad(makeKeymap(keys),rowPINS,colPINS, ROWS, COLS);
LiquidCrystal_I2C lcd(0x27,20,4); // set the LCD address to 0x20 for a 16 chars and 2 line display

//setup vars
const int stp = 12; // connect pin 12 to step
const int dir = 13; // connect pin 13 to dir
const int StepsPerRotation = 204; // Set Steps per rotation of stepper 1 Revolution = 0.5°
const int TableRatio = 72; // ratio of rotary table
const int Multiplier = (StepsPerRotation * TableRatio)/360; // 200*90=18000/360 = 50  orginal: (StepsPerRotation * TableRatio)/360
const int stepdelay = 1;
float Degrees = 0; // Degrees from Serial input
float ToMove = 0; // Steps to move
float bob = 0;
int cho = 0;

void setup()
{
lcd.init(); // initialize the lcd
pinMode(stp, OUTPUT);
pinMode(dir, OUTPUT);

// Print welcome message to the LCD.
lcd.backlight();lcd.print("Rotary Table");
lcd.setCursor(4,2);lcd.print("...");
lcd.setCursor(3,3);lcd.print("...);
delay(2000);
lcd.init();
cho = 0;
char key = kpd.getKey();
lcd.print("Enter Selection:");
lcd.setCursor(0,1);lcd.print("Degrees = A");
lcd.setCursor(0,2);lcd.print("Divisions = B");
lcd.setCursor(0,3);lcd.print("JOG = C");
while(cho == 0)
{
key = kpd.getKey();
switch (key)
{
case NO_KEY:
break;
case 'A':
Degrees=getdegrees();
lcd.clear();
cho = 1;
break;
case 'B':
Degrees=getdivisions();
cho=2;
break;
case 'C':
Degrees=getjog();
lcd.clear();
cho=3;
break;
} // end case
} // end while cho=0
} // end setup

void loop() // MAIN LOOP
{
lcd.clear();
char key = kpd.getKey();
bob = 0;
lcd.setCursor(7,0);lcd.print("Total: ");lcd.print(bob,2); // total steps
lcd.setCursor(0,3);lcd.print("FOR=A REV=B X=C");
while(key != 'C') // C will return to start menu
{
lcd.setCursor(0,0);lcd.print(abs(Degrees),2);lcd.print((char)223);
key = kpd.getKey();
if(key == 'A') // FORWARD
{
bob = bob + Degrees;
ToMove = (Degrees*Multiplier);
digitalWrite(dir, LOW);
printadvance();
}
if(key=='B') // REVERSE
{
bob = bob - Degrees;
ToMove = (Degrees*Multiplier);
digitalWrite(dir, HIGH); // pin 13
printadvance();
}
} // end while not C loop
lcd.init();
setup();
} // end main VOID


float getjog()
{
float Degrees = 0;
float num = 0.00;
char key = kpd.getKey();
lcd.clear();
lcd.setCursor(6,0);lcd.print("Jogging");
lcd.setCursor(0,1);lcd.print("A=1 B=10 C=100 Steps");
lcd.setCursor(0,2);lcd.print("Enter Degrees:");lcd.setCursor(0,3);lcd.print("OK = # ");lcd.print((char)60);lcd.print((char)45);lcd.print(" D");

while(key != '#')
{
switch (key)
{
case NO_KEY:
break;
case 'A':
Degrees = 1;
lcd.setCursor(14,2);lcd.print(Degrees);
break;
case 'B':
Degrees = 10;
lcd.setCursor(14,2);lcd.print(Degrees);
break;
case 'C':
Degrees = 100;
lcd.setCursor(14,2);lcd.print(Degrees);
break;
case 'D':
num=0.00;
lcd.setCursor(14,2);lcd.print(" ");
lcd.setCursor(14,2);
break;
}
key = kpd.getKey();
}
return Degrees;
}


float getdivisions()
{
float Degrees = 0;
float num = 0.00;
char key = kpd.getKey();
lcd.clear();
lcd.setCursor(0,1);lcd.print("Enter Division:");lcd.setCursor(0,3);lcd.print("OK = # ");lcd.print((char)60);lcd.print((char)45);lcd.print(" D");
lcd.setCursor(16,1);

while(key != '#')
{
switch (key)
{
case NO_KEY:
break;

case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
num = num * 10 + (key - '0');
lcd.print(key);
break;

case 'D':
num=0.00;
lcd.setCursor(16,1);lcd.print(" ");
lcd.setCursor(16,1);
break;
}
Degrees = 360/num;
key = kpd.getKey();
}
return Degrees; //num;
}


float getdegrees()
{
//int key = 0;
float num = 0.00;
float decimal = 0.00;
float decnum = 0.00;
int counter = 0;
lcd.clear();
//lcd.init();
char key = kpd.getKey();
lcd.setCursor(0,1);lcd.print("Enter Degrees:");lcd.setCursor(0,3);lcd.print("OK = # ");lcd.print((char)60);lcd.print((char)45);lcd.print(" D");
lcd.setCursor(15,1);
bool decOffset = false;

while(key != '#')
{
switch (key)
{
case NO_KEY:
break;

case '.':
if(!decOffset)
{
decOffset = true;
}
lcd.print(key);
break;

case 'D':
num=0.00;
lcd.setCursor(15,1);lcd.print(" ");
lcd.setCursor(15,1);
break;

case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
if(!decOffset)
{
num = num * 10 + (key - '0');
lcd.print(key);
}
else if((decOffset) && (counter <= 1))
{
num = num * 10 + (key - '0');
lcd.print(key);
counter++;
}
break;
} //end case
decnum = num / pow(10, counter);
key = kpd.getKey();
} //end while not #
return decnum;
} // end getdegrees

void printadvance() // print function
{
lcd.setCursor(6,1);lcd.print("Moving");
lcd.setCursor(4,2);lcd.print("Steps ");lcd.print(ToMove,0);
lcd.setCursor(13,0);lcd.print(bob,2);
rotation(ToMove,0);
lcd.setCursor(6,1);lcd.print(" ");
}

void rotation(float tm, int d)
{
for(int i = 0; i < tm; i++)
{
digitalWrite(stp, HIGH);
delay(stepdelay);
digitalWrite(stp, LOW);
delay(stepdelay);
}
}

void software_Reset() // Restarts program from beginning but does not reset the peripherals and registers
{
asm volatile (" jmp 0");
}

Table rotation is one
Shaft rotation is 72
Stepper full step is 200
Stepper driver microstep = ?
Gear box is 30 [ error see post 6 ]

30 x ? X 200 x 72 = steps per table rotation

1 table rotation = 360 degree

I read that as 6000 pulses for 5 degree turning of the table. Yes, x … if microstepping is used.

why "gear box" 30? it's a 50:1 gearbox.

again, it needs 204 steps to turn the shaft one full revolution. If i go 200, it's about 2-3° shy on the worm gear shaft, that makes it under 5° on the table, 4.8 or something. i dont know why but that's how it is.

so 204 steps times 72 = 14688 steps to turn the table one full 360°

and on the sidenote, microstepping (the driver) is set to the position that 200 is active

even with this all, it eludes me how to put that into the code.

as i understand it, i only need to change the values of the int, and maybe correct the int Multiplier.

if i edit now the code to:

//setup vars
const int stp = 12; // connect pin 12 to step
const int dir = 13; // connect pin 13 to dir
const int StepsPerRotation = 204; // Set Steps per rotation of stepper 1 Revolution = 0.5°
const int TableRatio = 72; // ratio of rotary table
const int Multiplier = (StepsPerRotation * TableRatio)/360; // 204 * 72 = 14.688 / 360 = 40.8
const int stepdelay = 1;
float Degrees = 0; // Degrees from Serial input
float ToMove = 0; // Steps to move
float bob = 0;
int cho = 0;

It should give me 1° = 40.8 Steps

now it i try 90°, the readout say: 3600 steps :o and it moves like 1 degree....
sorry, i am completely lost with your answers

now it moves at least a good bit more:

const int stp = 12; // connect pin 12 to step
const int dir = 13; // connect pin 13 to dir
const float StepsPerRotation = 200; // Set Steps per rotation of stepper
const float TableRatio = 72*50; // ratio of rotary table
const float Multiplier = (StepsPerRotation * TableRatio)/360;
const int stepdelay = 1;
float Degrees = 0; // Degrees from Serial input
float ToMove = 0; // Steps to move
float bob = 0;
int cho = 0;

included the 50:1 to the preexisting 72:1 Gear (multiplied, because it takes 50 times more than with a normal stepper, as it has a 50 reduction right?)
changed the int to float, just for good messure as i had sometimes wrong outputs

edit:
i give up, this is not working out for me anyway as it is dead slow

The variable Multiplier is declared as an int. 14688/360 will make a fraction being lost and likely some inaccuracy.

Adding 50? Not multiplying by 50?

Sorry, dirt on my phone.

Sounds like you have 4 steps of gear backlash. Did you say the gear ratio was 50 turns of input shaft for exactly 1 turn of table?
That's 10000 steps for a 200 step per rev motor.

Railroader:
Adding 50? Not multiplying by 50?

yeah first draft was a mistake on my side

@JCA34F
yes the gear ratio is 50 (4397/4913) This one:

i am a bit confused as the datasheet say its a 50:1 and the online page says its a 51:1
maybe that's the reason for the slight error

anyway, it still does not work properly.

i changed from INT to float as said, because of the fraction problem.

This is the actual code, if you can tell me if it is OK or if something is wrong, with the correction would help the best, unless there is something not yet clear:

const int stp = 12; // connect pin 12 to step
const int dir = 13; // connect pin 13 to dir
const float StepsPerRotation = 200; // Set Steps per rotation of stepper
const float TableRatio = 72*50; // ratio of rotary table
const float Multiplier = (StepsPerRotation * TableRatio)/360;
const int stepdelay = 1;
float Degrees = 0; // Degrees from Serial input
float ToMove = 0; // Steps to move
float bob = 0;
int cho = 0;

again, microsteps are set to 1 (200 pluses)

So the actual ratio is 1 : 50.8949725219, TableRatio will be 3664.43802158 instead of 3600 and Multiplier will be 2035.79890088 instead of 2000. So 2035.79890088 / 2000 = 1.01789945044 * 200 steps = 203.579890088. Hmmm. There's your (almost) 4 steps :confused:

Are You familiar with the term "Back Lash"? If You run Your test in only one direction You don't need to bother.
@JCA34F
No, that can't be a possible explanation. Rotating tables use worm gears and most likely the geared motor. They have a much greater backlash than that.

The calculations in this code most be off some how....I cant get 3200steps as I need for a full 360!
give me 2880steps 200(nema23)*16(microstep)/360=2880??

Any real CNC program will take the change of direction backlash into consideration each time the direction is changed.

Paul

Paul_KD7HB:
Any real CNC program will take the change of direction backlash into consideration each time the direction is changed.

Paul

One could think that but a friend using less than high level system will nit agree witj You.
@OP measure the backlash, in steps, and add that number whenever the durectiin is changed. My home made CNC does it and it works well.