1. Originally Posted by Robin Hewitt
I have a working G code reader written in C# for Microsoft Visual Studio if that would help?

It's only really interested on G0-3 and tool changes but could be expanded.
Thanks Robin, I'm sure it'll save me some effort... I'll PM you my email in case you've lost it :)

2. Oops, forgot the cutarc() subroutine

Let me know what else I forgot

Robin

3. Originally Posted by Robin Hewitt
Oops, forgot the cutarc() subroutine

Let me know what else I forgot

Robin
Thanks.

Been playing around with interpolation routines but run into a snag... so need to go back and rethink the code I've written. Issue is this... in 2D to make it easy... want to move from 0,0 to 1000,1300 say (steps, not mm). Lets assume that the feed rate requires this to take 1 second... then the x rate is 1000steps/sec and the y rate is 1300 steps/sec. But I have a base rate of 5000 steps sec (10khz interrupt/2). so X is every 5th interrupt and y is every 3.85 interrupts.. but you cant do 3.85.. so i need a much higher interrupt rate and some interpolation... in this case 50000 and divisors of 38,38,39,38,38,39,38,38,38,39 per 5000 gives 1301 with a max error of 2 steps... So i need to get that kernel level interrupt working... in the meantime, i'll have to run it all at 1/10 speed :(

4. Originally Posted by irving2008
Thanks.

Been playing around with interpolation routines but run into a snag... so need to go back and rethink the code I've written. Issue is this... in 2D to make it easy... want to move from 0,0 to 1000,1300 say (steps, not mm). Lets assume that the feed rate requires this to take 1 second... then the x rate is 1000steps/sec and the y rate is 1300 steps/sec. But I have a base rate of 5000 steps sec (10khz interrupt/2). so X is every 5th interrupt and y is every 3.85 interrupts.. but you cant do 3.85.. so i need a much higher interrupt rate and some interpolation... in this case 50000 and divisors of 38,38,39,38,38,39,38,38,38,39 per 5000 gives 1301 with a max error of 2 steps... So i need to get that kernel level interrupt working... in the meantime, i'll have to run it all at 1/10 speed :(
You could try the Bresenham line algorithm, it extends to n dimensions.

5. Originally Posted by bobc
You could try the Bresenham line algorithm, it extends to n dimensions.
I'm already using a modified form of that. The issue isn't one however of where the line goes, but how fast it goes in each axis. If the pulse rate is derived from a fixed clock, then the granularity of the pulse rate is limited.

6. Originally Posted by irving2008
I'm already using a modified form of that. The issue isn't one however of where the line goes, but how fast it goes in each axis. If the pulse rate is derived from a fixed clock, then the granularity of the pulse rate is limited.
Well sure. It's a question of what level of accuracy you are aiming for, sub-atomic ? :)

Apparently on the Pi there is a USB interrupt at 8Khz which takes around 20% of the CPU, so getting a 50kHz interrupt might be a challenge.

7. It is fun isn't it, the hours I spent making it work. Everytime I thought I had it figured I found the next little snag

I find the major axis which steps on every interrupt, and slave everything else to that. I reload the timer after every step from the acceleration table, stretching the delay by 1.5 (approx root 2) if both X and Y go together.

I can give you the working code that drives my mills but it may not help being written in Z80 assembler. It runs from a pre-digested buffer of straight lines without any multiplies or divides. On a slow CPU, 8MHz, the interrupt steps anyone set to step on entry then reconfigures the step and direction lines at exit.

I'm a bit of a dinosaur.

8. Originally Posted by bobc
Well sure. It's a question of what level of accuracy you are aiming for, sub-atomic ? :)

Apparently on the Pi there is a USB interrupt at 8Khz which takes around 20% of the CPU, so getting a 50kHz interrupt might be a challenge.
No, but with 1 step = 0.05mm, a few steps out is problematic. I'm running at 10KHz interrupts now but there are reports of others handling 100KHz interrupts, using the PRE_EMPT flags in the kernel compile (another reason to re-compile). The only speed limit I have right now is the fact that the interrupt handler runs in user space so context switching is a significant part of the interrupt latency (about 50uS measured).

Originally Posted by Robin Hewitt
It is fun isn't it, the hours I spent making it work. Everytime I thought I had it figured I found the next little snag

I find the major axis which steps on every interrupt, and slave everything else to that. I reload the timer after every step from the acceleration table, stretching the delay by 1.5 (approx root 2) if both X and Y go together.

I can give you the working code that drives my mills but it may not help being written in Z80 assembler. It runs from a pre-digested buffer of straight lines without any multiplies or divides. On a slow CPU, 8MHz, the interrupt steps anyone set to step on entry then reconfigures the step and direction lines at exit.

I'm a bit of a dinosaur.
Thats essentially the way I am doing it. I have a buffer of 1024 'moves' but if I have to fill it with 1 step moves its going to need to be much bigger or the steppers are going to run out of work to do... Or did you convert the whole of the G-code into steps before putting it in the buffer? How big is your buffer?

How fast is your interrupt and do you change the rate? It occured to me that one way to control feed rate would be to have a programmable interrupt timer using the Pi's PWM generator - but that wastes a GPIO output pin as I don't think you can programme it to interrupt if its not allocated to an output pin (and possibly needs to be fed back to an input).

9. I have a buffer of straight lines. Lines currently are 24 bits long max. With the acceleration/deceleration/directions included I can define a straight line, XYZ, in 12 bytes.

I pinched the idea, I won't say where from. It also makes jogging easy but the buffer needs canny attention after you hit pause because unexpected braking has to become unexpected acceleration when you unpause.

I put a tidemark at 800 lines, if the buffer drops below that it gets another 10 lines. Drip feeding from the host may not be the way you want to go.

I use 2 interrupts, one for the stepping, one for the comms.

I have one bug at the mo', if the host misses a byte from the status report it waits forever for it to arrive. I need to add a timeout/retry. I haven't lost any data going the other way, yet, touch wood.

Edit: You step at .05mm? Is that a typo? I step at .005mm.
Last edited by Robin Hewitt; 01-08-2012 at 12:24 PM.

10. yes it was a typo...

I now have a working 3D modified/optimised Bresenham run-length algorithm. I interpret the G-Code file (or will do soon) and write the run length data to a file. When you press 'go' it just reads the file and fills the buffer, then keeps it topped up. With over 3Gb of storage available on the SD card I dont need to worry about running out of memory! I added a second 'playback' buffer so once the interrupt handler outputs the steps to the stepper it puts what it just did in the playback buffer. This is then used by the visualisation routines which run at a low priority...

Still got to work on acceleration and deceleration approaches...

Page 4 of 6 First ... 23456 Last

#### Posting Permissions

• You may not post new threads
• You may not post replies
• You may not post attachments
• You may not edit your posts
•