cnc

General FreeBASIC programming questions.
Turd
Posts: 175
Joined: Aug 31, 2007 23:34
Location: Saskatchewan, Canada

cnc

Post by Turd »

I'm trying to make a cnc machine but I'm not sure how I would write the part that makes the stepper motors take turns stepping to move the table in a straight line from one point to another. Kind of like the "Line" command.

Example:
Image

I guess it would have to find out the ratio of steps or something...
Any ideas?
Dinosaur
Posts: 1478
Joined: Jul 24, 2005 1:13
Location: Hervey Bay (.au)

Post by Dinosaur »

Hi all

I use steppers a lot, but never for what you want to do.
However, you are going to need feedback, to confirm the position you are in at any one time. Then you will need to plot to each point by driving each motor the right number of steps, at the same time , to reach your target.
Keep recalculating your speed and target position, based upon your current position.

The actual sequence of driving each phase to get a step in the right direction
at the right speed, may be difficult if you are doing it from within your program instead of a dedicated hardware device that you talk to.

Regards
MichaelW
Posts: 3500
Joined: May 16, 2006 22:34
Location: USA

Post by MichaelW »

For a stepper motor system I would think an efficient sequence of positions could be calculated with something like Bresenham’s line algorithm.
Rens
Posts: 256
Joined: Jul 06, 2005 21:09

Post by Rens »

Removed by me
Last edited by Rens on Oct 27, 2010 17:57, edited 1 time in total.
Turd
Posts: 175
Joined: Aug 31, 2007 23:34
Location: Saskatchewan, Canada

Post by Turd »

Thanks a lot!
If I can ever get everything to work I post it here :)
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Post by D.J.Peters »

I know homemade cnc and milling are a great hobby but it exist one FREE "standard" solution to handle the part of software.
building the whole hardware is enough fun :-)

forum: http://www.linuxcnc.org/component/option,com_kunena/
wiki: http://wiki.linuxcnc.org/cgi-bin/emcinfo.pl
download: http://sourceforge.net/projects/emc/
Richard
Posts: 3096
Joined: Jan 15, 2007 20:44
Location: Australia

Post by Richard »

Code: Select all

'==================================================================
' Triaxial stepper motors in a straight line
'==================================================================
' feed rate and step rate are limited by variable stepTime
Dim Shared As Double stepTime = .02 ' set time in seconds between steps
Dim Shared As Double waitUntil      ' wait until time for next move 

'==================================================================
Sub steppers(Byval x As Integer, Byval y As Integer, Byval z As Integer)
    ' x, y and z are now rounded to integers
    Do
    Loop Until Timer > waitUntil
    '--------------------------------------------------------------
    ' here you convert x, y & z integers to stepper phase patterns and
    '   then output them to the stepper motors
    Pset (x,y), 14   ' screen demo
    'print x, y, z
    '--------------------------------------------------------------
    waitUntil = Timer + stepTime    ' minimum step time delay in seconds
End Sub

'==================================================================
Sub Move3D(_    ' 3D straight line move
    Byref xold As Double,_
	Byref yold As Double,_
	Byref zold As Double,_
	Byref xnew As Double,_
	Byref ynew As Double,_
	Byref znew As Double)
    
    Dim As Double xdist, ydist, zdist
	xdist = xnew - xold
	ydist = ynew - yold
	zdist = znew - zold
	
    ' find maximum distance
    Dim As Double maxdist = Abs(xdist)
	If maxdist < Abs(ydist) Then maxdist = Abs(ydist)
    If maxdist < Abs(zdist) Then maxdist = Abs(zdist)
	
    ' signed step sizes, all are <= 1.0000
    Dim As Double xstep, ystep, zstep
    xstep = xdist / maxdist 
	ystep = ydist / maxdist
	zstep = zdist / maxdist
    
	' step along the line
    For i As Integer = 1 To maxdist ' now draw the line
		xold = xold + xstep
		yold = yold + ystep
		zold = zold + zstep
        steppers(xold, yold, zold)
    Next i
    
    ' eliminate any fp roundoff 
    xold = xnew
    yold = ynew
    zold = znew
    steppers(xold, yold, zold)
End Sub

'==================================================================
' demo and test
Screen 19
Move3d (100, 320, 130, 200, 120, 131)

'==================================================================
Sleep
'==================================================================
Turd
Posts: 175
Joined: Aug 31, 2007 23:34
Location: Saskatchewan, Canada

Post by Turd »

Thank for all the help!

I got a new problem now. I want to run the steppers using a circuit that only need two pins to run a unipolar stepper motor. It need this pattern to step a motor:
00
01
11
10
then loop
I want to run two (x and y) or three (x, y and z) from the data port (8 pins) on the parallel port.

This is what I have so far but it doesn't work:

Code: Select all

declare sub cw_motor_x(steps as integer)
declare sub cw_motor_y(steps as integer)

do while inkey$ = ""
	cw_motor_x 4
	cw_motor_y 4
loop

sub cw_motor_x(steps as integer)
	dim as integer i
	for i = 1 to steps
		'&b******00
		if not inp(888) and 2 and not inp(888) and 1 then
			'&b******01
			out 888, inp(888) + 1
			
		'&b******01
		elseif not inp(888) and 2 and inp(888) and 1 then
			'&b******11
			out 888, inp(888) + 2
			
		'&b******11
		elseif inp(888) and 2 and inp(888) and 1 then
			'&b******10
			out 888, inp(888) - 1
			
		'&b******10
		elseif inp(888) and 2 and not inp(888) and 1 then
			'&b******00
			out 888, inp(888) - 2
			
		end if
		sleep 100
	next i
end sub


sub cw_motor_y(steps as integer)
	dim as integer i
	for i = 1 to steps
		'&b****00**
		if not inp(888) and 8 and not inp(888) and 4 then
			'&b****01**
			out 888, inp(888) + 4
			
		'&b****01**
		elseif not inp(888) and 8 and inp(888) and 4 then
			'&b****11**
			out 888, inp(888) + 8
			
		'&b****11**
		elseif inp(888) and 8 and inp(888) and 4 then
			'&b****10**
			out 888, inp(888) - 4
			
		'&b****10**
		elseif inp(888) and 8 and not inp(888) and 4 then
			'&b****00**
			out 888, inp(888) - 8
			
		end if
		sleep 100
	next i
end sub
I have LEDs on the parallel port. I tested the LEDs already (out 888, 255)
I'm probably doing this very stupidly lol
phishguy
Posts: 1201
Joined: May 05, 2006 16:12
Location: West Richland, Wa

Post by phishguy »

Try this:

Code: Select all

Declare Sub  cw_motor_x(steps As Integer)
Declare Sub cw_motor_y(steps As Integer)
 
 
Do While Inkey$ = ""
        cw_motor_x(1)
       
        cw_motor_y(1)
        print bin(inp(888),8)
         
Loop

Sub cw_motor_x(steps As Integer)
        Dim As Integer i
        dim as ubyte a
        For i = 1 To steps
                '&b******00
                a = inp(888) and 3 
                select case a
                case 1
                      '&b******01 
                        Out 888, Inp(888) + 2
                       
                '&b******01
               case 3
                        '&b******11
                        Out 888, Inp(888) - 1
                       
                '&b******11
                case 2 
                        '&b******10
                        Out 888, Inp(888) - 2
                       
                '&b******10
                case 0 
                        '&b******00
                        Out 888, Inp(888) + 1
                         
                        
              end select
               
                Sleep 100
        Next i
End Sub


Sub cw_motor_y(steps As Integer)
        Dim As Integer i
        dim a as ubyte
        For i = 1 To steps
                '&b****00**
                a = inp(888) and 12
               select case a
               case 4
                        '&b****01**
                        Out 888, Inp(888) + 8
                       
                '&b****01**
                case 12  
                        '&b****11**
                        Out 888, Inp(888) - 4
                       
                '&b****11**
               case 8 
                        '&b****10**
                        Out 888, Inp(888) - 8
                       
                '&b****10**
               case 0
                        '&b****00**
                        Out 888, Inp(888) + 4
                       
                end select
                
                Sleep 100
        Next i
End Sub
<edit>
Here's an update for 4 motors using 1 sub.

Code: Select all

Declare Sub  cw_motor(motor as integer,steps As Integer)
Declare Sub  ccw_motor(motor as integer,steps As Integer) 
 
out 888,0
Do While Inkey$ = ""
        cw_motor(1,1)
        cw_motor(2,1)
          cw_motor(3,1)
           cw_motor(4,1)
        print bin(inp(888),8)
         
Loop

Sub cw_motor(motor as integer,steps As Integer)
        Dim As Integer i
        dim as ubyte a
        dim moffset as integer
        moffset = 4^(motor-1)
       
        
        For i = 1 To steps
                '&b******00
                a = inp(888) and (3 * moffset)
                select case a
                case moffset
                      '&b******01 
                        Out 888, Inp(888) + (2 * moffset)
                       
                '&b******01
               case 3 * moffset
                        '&b******11
                        Out 888, Inp(888) -   moffset
                       
                '&b******11
                case 2 * moffset
                        '&b******10
                        Out 888, Inp(888) - (2 * moffset)
                       
                '&b******10
                case 0 
                        '&b******00
                        Out 888, Inp(888) +  moffset
                         
                        
              end select
               
                Sleep 100
        Next i
End Sub

Sub ccw_motor(motor as integer,steps As Integer)
        Dim As Integer i
        dim as ubyte a
        dim moffset as integer
        moffset = 4^(motor-1)
       
        
        For i = 1 To steps
                '&b******00
                a = inp(888) and (3 * moffset)
                select case a
                case moffset
                      '&b******01 
                        Out 888, Inp(888) - moffset
                       
                '&b******01
               case 3 * moffset
                        '&b******11
                        Out 888, Inp(888) - (2 * moffset)
                       
                '&b******11
                case 2 * moffset
                        '&b******10
                        Out 888, Inp(888) + moffset 
                       
                '&b******10
                case 0 
                        '&b******00
                        Out 888, Inp(888) +  (2 * moffset)
                         
                        
              end select
               
                Sleep 100
        Next i
End Sub


 

 
Turd
Posts: 175
Joined: Aug 31, 2007 23:34
Location: Saskatchewan, Canada

Post by Turd »

Awesome! Thank you!
Richard
Posts: 3096
Joined: Jan 15, 2007 20:44
Location: Australia

Post by Richard »

Having CW and CCW code makes it very difficult to move in straight diagonal lines. Instead it is much easier to declare three counters such as X, Y and Z. Then each time you change one you update the parallel port pattern for all. Any code can then change those shared x, y & z axis counters by incrementing or decrementing them and you do not need to keep track of step state or direction.

The code conversion and port bit mapping are now looked up in the three predefined code arrays. Comment in the out port and comment out the demo print.

Code: Select all

'==================================================================
' Triaxial stepper motors in a straight line via Parallel Port
'==================================================================
' feed rate and step rate are limited by variable stepTime
Dim Shared As Double stepTime = .01  ' safe time in seconds between steps
Dim Shared As Double waitUntil      ' time when safe for next move 

' these arrays map the step counter sequence to port bits.
Dim Shared As Integer Xgray( 0 To 3) => {0,  1,  3,  2}	' *1 , bits 0 and 1
Dim Shared As Integer Ygray( 0 To 3) => {0,  4, 12,  8}	' *4 , bits 2 and 3
Dim Shared As Integer Zgray( 0 To 3) => {0, 16, 48, 32}	' *16, bits 4 and 5

Const As Integer Parallel_Port = 888

'==================================================================
Sub steppers(Byval x As Integer, Byval y As Integer, Byval z As Integer)
    ' x, y and z are now rounded to integers
    Do
    Loop Until Timer > waitUntil ' when it will be safe to step
    ' convert x, y & z integers to stepper phase bit patterns
    Dim As Integer BitPattern = Xgray(x And 3) Or Ygray(y And 3) Or Zgray(z And 3)
    ' uncomment the next line to output data to parallel port
    ' Out ParallelPort, BitPattern ' output gray codes to the stepper motors
    Print Bin(BitPattern, 8)    ' this line is demonstration code only
    '--------------------------------------------------------------
    waitUntil = Timer + stepTime    ' minimum step time delay in seconds
End Sub

'==================================================================
Sub Move3D(_    ' 3D straight line move
    Byref xold As Double,_
	Byref yold As Double,_
	Byref zold As Double,_
	Byref xnew As Double,_
	Byref ynew As Double,_
	Byref znew As Double)
    
    Dim As Double xdist, ydist, zdist
	xdist = xnew - xold
	ydist = ynew - yold
	zdist = znew - zold
	
    ' find maximum distance
    Dim As Double maxdist = Abs(xdist)
	If maxdist < Abs(ydist) Then maxdist = Abs(ydist)
    If maxdist < Abs(zdist) Then maxdist = Abs(zdist)
	
    ' signed step sizes, all are <= 1.0000
    Dim As Double xstep, ystep, zstep
    xstep = xdist / maxdist 
	ystep = ydist / maxdist
	zstep = zdist / maxdist
    
	' step along the line
    For i As Integer = 1 To maxdist ' now draw the line
		xold = xold + xstep
		yold = yold + ystep
		zold = zold + zstep
        steppers(xold, yold, zold)
    Next i
    
    ' eliminate any fp roundoff 
    xold = xnew
    yold = ynew
    zold = znew
    steppers(xold, yold, zold)
End Sub

'==================================================================
' demo and test
Screen 19
Move3d (100, 100, 100, 116, 108, 101) ' short move to test x, y and z

'==================================================================
Sleep
'==================================================================
Turd
Posts: 175
Joined: Aug 31, 2007 23:34
Location: Saskatchewan, Canada

Post by Turd »

Ok, so I scrapped the first couple of cncs that I was working on because they were no good lol.
Heres the good one :D

Image

Sorry for the dark pic.

Image

Image

I want to run it though the serial port. I want a PICAXE micro-controller to control the motors but I'm having a little trouble.

Heres the FB code:

Code: Select all

dim as integer i

shell "stty -F /dev/ttyS0 speed 9600"
sleep 1000
if open com( "/dev/ttyS0:9600,n,8,1,cs0,cd0,ds0,rs" as #1 ) <> 0 then
  locate 1, 1
  print "Unable to open com port"
  end
end if

sleep 2000

do
	print #1, &b00100010, &b00000010;
	sleep 100
	print #1, &b01000100, &b00000100;
	sleep 100
	print #1, &b00010001, &b00000001;
	sleep 100
	print #1, &b10001000, &b00001000;
	sleep 100
loop
Heres the PICAXE code:

Code: Select all

#no_data
#no_table
setfreq m4
dirsb = %11111111
dirsc = %11111111
disconnect
do
	serrxd b0, b1
	pinsb = b0
	pinsc = b1
loop
Running this on the PICAXE runs the motors just fine:

Code: Select all

#no_data
#no_table
dirsb = %11111111
dirsc = %11111111
do
	pinsb = %00100010
	pinsc = %00000010
	pause 3
	pinsb = %01000100
	pinsc = %00000100
	pause 3
	pinsb = %00010001
	pinsc = %00000001
	pause 3
	pinsb = %10001000
	pinsc = %00001000
	pause 3
loop
Any ideas?

PICAXE manuals:
http://www.picaxe.com/Getting-Started/PICAXE-Manuals/

serrxd is on page 207 of this one:
http://www.picaxe.com/docs/picaxe_manual2.pdf
phishguy
Posts: 1201
Joined: May 05, 2006 16:12
Location: West Richland, Wa

Post by phishguy »

I'm just guessing since I haven't done anything with a pickaxe before. But, I would imaging that you would want to replace the commas in the sending code with a semicolon. Otherwise your sending code will send out a tab. I would also recommend some sort of command format for sending and receiving data. Something like SOT, number of bytes, bytes, possibly a checksum, and then EOT. This would make synchronizing of the data between the PC and the PICAXE much more robust and less prone to data errors.

Code: Select all

do
        print #1, &b00100010; &b00000010;
        sleep 100
        print #1, &b01000100; &b00000100;
        sleep 100
        print #1, &b00010001; &b00000001;
        sleep 100
        print #1, &b10001000; &b00001000;
        sleep 100
loop
 
[edit]
BTW - your CNC platform looks pretty cool. Did you build it from plans, or did you design it yourself? I've always wanted to build one. But, I've never had the time, money, or fabricating equipment and skills.
Dinosaur
Posts: 1478
Joined: Jul 24, 2005 1:13
Location: Hervey Bay (.au)

Post by Dinosaur »

Hi all

It looks like you are timing and switching each phase changeover.
My experience with trying to switch the phases on the stepper motor;
1:You spent to much cpu time timing and controlling the phases.
2:You can't achieve the speed of rotation.
3:Resolution of Timing isn't good enough for smooth operation.

So, I would get a very cheap stepper board like this one
http://www.oceancontrols.com.au/KTA-179.html
which doesn't need the massive heatsinks.(unless that is your power supply) I use a similar motor
http://www.oceancontrols.com.au/MOT-128.html with the above board.

Then use the serial port with the PicAxe or other PIC and let the it do the clocking for speed only. So, tell the PIC "Motor(n) , Fwd, speed, Nbr of steps"

You can then use the PC to calculate the trajectory and update the pic via serial, allowing an acceleration curve as well as a decelleration.

Let the mundane job of phase control be done by a dedicated chip/board.

Regards
phishguy
Posts: 1201
Joined: May 05, 2006 16:12
Location: West Richland, Wa

Post by phishguy »

I would have to agree with Dinosaur that a 2 or 3 axis stepper control board would be a better way to go. If you still want to develop that portion on your own, I would suggest looking at a different micro such as a Parallax Propeller. There have been several hobbyists out there that have developed CNC controllers using this micro. However, off the shelf controllers would make the development time much quicker.
Post Reply