CNC Dividing Head - PICAXE microcontroller

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.
You can also get an extra bit sometimes by using the carry flag, assuming this processor has one and shift/rotate instructions that go through it. Shift left through the carry bit gives you *2 with the most significant bit hanging out in the carry, and shift-right does the same thing for divide but with the least significant bit there.

There are also vast math routines available for tiny micros like this, but maybe more effort and difficulty than needed.

Aw rats, I just remembered you're using some higher level language to program these. I have no idea if they use the carry bit sensibly or give you access to shift commands.

Edit: is there some flag to let you know you've overflowed? Then you could just handle that case as two moves.



 
Don't know about the carry flag. Haven't gotten that far yet. My current ploy is to see if there is a way to do this without using big numbers. I looking at using the modulus function and trying to do something with remainders. In the end, I may just restrict it to 45 divisions or less. Got the capacity to handle that with no issues. However, it would be nice to go up to 120 or more, just to say I could!

Chuck
 
Since there's always a maximum (practical) amount of divisions you will need, the best way to do it on a pic micro is to use a table, pre-calculated with the steps needed for each and use the program memory to store these values. They do this in the automotive industry's ECU's to avoid engine calculations "on the fly"
 
Noitoen said:
Since there's always a maximum (practical) amount of divisions you will need, the best way to do it on a pic micro is to use a table, pre-calculated with the steps needed for each and use the program memory to store these values. They do this in the automotive industry's ECU's to avoid engine calculations "on the fly"

That would be pretty good option if I had some memory to speak of. The little PICAXE only has 48 words (or bytes) of memory. I may be trying to do to much with too little. This is primarily a learning exercise for me, so maybe I should be content with up to 45 divisions. But, I'm always up for a challenge. I probably need someone like Marv to come along and say, "Sorry, Chuck, but the physics involved dictate that it can't be done!" :)

Chuck
 
I'm not talking about ordinary ram. Tables can be stored in program memory, but then I program in assembly and I don't know if Picaxe has instructions for it. Normal basic language has and usually it is listed as "data" at the end of the program. Some of the higher level languages also let you use assembly instructions so you could also implement this.
 
Look for a SET or DECLARE function. Something that lets you assign a value to a variable.
Then just "decalre" a whole bunch of variables in the program for use in a matrix look up table.

Is that what you are getting at Noitoen?
 
Does the PicAxe support modulo arithmetic?
 
Shred, yes, the picaxe basic language does have a modulo command. You can either use % or // as in 5 // 3 = 2. The PICAXE also always rounds up, so 3 / 5 = 1. It's a very simple basic and I expect each basic command translates to no more than 4 or 5 assembler commands. Also, there are no variables, only registers. You can assign a symbol name to a register so it looks like a variable, but you are limited to the bits that the register can hold. Basic commands like "Let B0 = B0 +1" or "Let B0 = B0 + B1" are valid. However, the following command, which combines more than 1 arithmetic operation, is not valid: "Let B0 = B1 + B2 / 3". You can't do an arithmetic command which requires an intermediate result. It's pretty unsophisticated.

On the positive side, it does have some pretty sophisticated input / output commands. There is Serial Read, Serial Write, ReadADC which reads an analog signal and converts it to digital, and a PWM output command which will output a Pulse Width Modified signal where you can specify the duty cycle for driving a variable speed DC motor.

Noitoen, if I understand your suggestion right, I would need a set of steps for each division I potentially wanted to use. For example, 47 divisions to a circle would require a table of 47 step values, 46 would require a separate table of 46 step values, 41 would require still another table with 41 step values, etc. What I'm aiming at doing, and it may not be within my grasp to do it, is be able to do any number of divisions from 1 (ok, 2) to 120
 
I will think a while on the matter in particular and will come back to you tomorrow.

Just tell me what is your dividing head's gear ratio and stepper motor's steps per revolution.
 
Noiten, the stepper motor has 48 steps per revolution and the gear ratio is 30 to 1 giving an overall step count of 1440 per revolution.

Thx...
Chuck
 
Ok, I've looked at the problem and came to the following conclusion:

To work without decimal point, and since the resolution of you stepper motor is only 48 steps or 96 half steps, your maximum none accumulative precision or occasional offset error will be 0,25º or 0,125º using half steps. If you were using a 200 step motor this error would only be 0,06º or 0,03º in half steps.

The first thing you have to do is, create a routine with a counter that allows you to move your motor any amount of steps from 0 to 1440, thus when you say go to 720, the dividing head will move a half turn. If you say go to 0 then it goes back to the original position and so on. If you can accomplish this the rest will be easy.

Can PicAxe multiply and divide 16 bit numbers? Can you handle LCD displays and switches?

You wont need any tables, all you have to do is, define the number of divisions you want, start a separate counter from 1 to the desired division and call this the "work division", now multiply this number by 1440 and divide by the divisions. The result will be the "go to" number for the motor. This is better than assuming a fixed number for the division because the fractional error will not accumulate.

If you don't understand what I mean, I'll explain it with an example.
 
Chuck,

I'm confused. Are you intending to drive the dividing table directly with the stepper output? On all the automated DHs I've seen, the stepper drives the worm of a normal rotary table so one has the added error reduction of the worm gear setup.

For example, suppose the RT has a typical 90:1 reduction worm gear setup. Then one rotation of the handwheel is 4 deg of table movement or 4*3600 = 14400 arc seconds.
With your stepper driving the handwheel, its 1440 steps would then yield a table movement of 10 arc seconds per stepper step.

With that sort of resolution, a lost step or two would be inconsequential - 10 arc seconds is a mighty small error.

If I've completely misunderstood (something at which I'm a master), just ignore this post.
 
Wouldn't the stepper and the rotary table drive have to be synced somehow at a primary 'zero' spot and then rezeroed again and again? Meaning the continued plus and minus operations and the backlash of the mechanical drive train in the rotary table, could combine and leave you several degrees 'off' at the end of executing a long program without doing it.


Would driving the rotary in only one direction keep the gear backlash from affecting the stepper count? Would that depend on the accuracy of the gearing?

Lots of questions,
Kermit
 
The way I understood is that he has a dividing head, small I suppose, with a 1:30 worm gear to be coupled to a 48 step motor giving a 0,25º resolution. If the drive is made the way I explained then there is no need for backlash compensation since the the motor can be moved anywhere to any "home" position and the the internal counter zeroed. Now the first move will take it to the first "machining" position, the second to the second and so on. Since its always moving in the same direction there is no need for backlash compensation. For a 6 side division the motor would move fro 0 to position 240 then 480, 720, 960, 1200 and finally 1440 (equals 0). No error in division here.

The first of the explanation was to make the system able to "go to" any desired position and not the function itself. Once his able to get the table to move to any possible position then the rest is easy.
 
Sorry for all the confusion. The stepper motor is actually a stepper gear motor with the gear train built in. The output shaft of the gearmotor has a 1 : 30 ratio with the motor. The motor, itself, has 48 steps per revolution. Thus, the output shaft has a resolution of 1440 : 1. This motor was used in a telescope tracking system. 1440 just happens to be the number of seconds in a 24 hour day... not that that has anything to do with this application. Backlash on this little gearmotor is neglible.

Marv, I'm not planning to drive a rotary table, but rather a dividing head. It will run in one direction, at least initially, or until my programming skills with the controller allow me to make it more sophisticated. My initial application is simply to index gear blanks for cutting teeth.

Again, this is an educational endeavor, so I'm mostly exploring the capabilities of the microcontroller, renewing my programming skills after probably 20 years of being idle, and improving my knowledge of stepper and controller electronics.

I do appreciate everyone's input. I'm certainly no math whiz!

Chuck
 
In that case you get better precision and have to multiply 1440 by the dividing head's ratio.
 
I think the question becomes "where do you want the error?" All at the end of 360 or spread throughout the divisions?

I'd do something like StepsPerRotation MOD NeededDivisions. Get a zero and you're golden. Any other value is the number of extra steps you have to sneak in somewhere along the way. There are various strategies on adding in extra steps here and there; spread them throughout the range, put them all at the end, every quarter, etc, but none of them are perfect.

Say 48 divisions-- 1440 MOD 48 = 0. Thus each division is exactly 1440 / 48 = 30 steps.

Say 49 divisions. 1440 MOD 49 = 19. Each division is 1440 / 49 = 29 steps per division, but now you've got 19 steps to wedge in throughout the 360 degrees as desired. Stick them all at the end and the divisions will all except one be equally spaced, put them elsewhere and divisions won't be equally spaced, but there won't be one that's way out.
 
Shred, it's funny how when I get into math mode, I don't think about the physical side of things. For example, I had never thought of the remainder as the count of additional steps that need to be inserted in addition to the steps per division. I'll have to think about this angle for a bit and see if I can come up with something.

Chuck
 
Chuck,

Damn you! I couldn't get your problem out of my head all last night. While showering this morning I worked out a candidate scheme that's outlined below.

I haven't analyzed it exhaustively so it may be flawed but I'll offer it up for your consideration. Even if it's unworkable, it may trigger an ah-ha in your mind that leads to a workable scheme.

The basic idea is to compute the number of steps for one division, I, and then divide this number into its integer and fractional parts. These parts are stored separately in a table in the m/c and used to reconstruct the number of steps needed for the current division number, K.

In my example, I've used a scaling factor of 1000 to make the algorithm operation transparent. Since we need to divide by this factor in the m/c, it may make more sense to use a factor that's a power of two so division can be accomplished by shifting.

Workable or not, the scheme has a serious flaw in that it's limited to 65 divisions before you run into overflow problems. At the moment I can't think of any clever way around that. Maybe you'll have an insight.



Exterior to the m/c compute:
(numbers in braces {} are a numerical example}

-----------------------------------------------

N = number of divisions desired {49}

I = 1440/N = steps/division {1440/49 = 29.387...}

A = int {29}

B = int[1000*(I-A)] {int[1000*(29.387-29)] = 387}

-----------------------------------------------

Store A and B for each value of N in a table in the m/c

Now to calculate the number of steps in the m/c...


-----------------------------------------------

K = step number (1 <= K <= N) {47}

S = number of steps = K*A + K*B/1000 {S = 47*29 + 47*387/1000 = 1363 + 18189/1000
= 1363 + 18 = 1381}

-----------------------------------------------

The value of B cannot exceed 999 and the maximum value of K is N so

L = K*B <= N*999

L cannot exceed 65535 to avoid overflow. This implies that the N < 65535/999 = 65 so this scheme would not work for N > 65. In gear cutting that could be a serious limitation.

 

Latest posts

Back
Top