CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Bresenham algorithm in a Pic 16c73A

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
john lee
Guest







Bresenham algorithm in a Pic 16c73A
PostPosted: Fri Nov 15, 2002 12:37 pm     Reply with quote

Hi, I have been using Pics for a few years now, has anyone written a useable interpretation of Jack Bresenham''s line algorithm for a Pic?I am using a 16c73a to drive a multi-axis machine, i.e to generate speed-ramped pulse trains in order to provide synchronised point-to-point moves, using a velocity profile.The move is not trapezoidal, but uses s-ramps to avoid the otherwise instantaneous torque foldback/windup at the turning-points. I am having problems with the interrupt latency.
System works, but, one of u has probably done it better!
Any contributions most welcome.
Regards,
Stigga the dump.
___________________________
This message was ported from CCS's old forum
Original Post ID: 9015
Doug Kennedy
Guest







Re: Bresenham algorithm in a Pic 16c73A
PostPosted: Fri Nov 15, 2002 1:52 pm     Reply with quote

This will draw a line between cartesian pts (x1,y1) (x2,y2)
plot (x,y,set) is a routine to turn on or off a pixel depending on the value of set.
Bresenham used the finite difference calculus to gain speed and avoid multipication. I have circle algorithms if you are interested



void line(long x1,long y1,long x2,long y2, int set)
{
long i,line_length,x,y;
signed long deltax,deltay,accm_error;
signed int xchange,ychange;
// bresenham algorithm for lines
disable_interrupts(GLOBAL);
X = x1 ;
Y = y1;

DeltaX = x2 - x1;
DeltaY = y2 - y1 ;
Ychange=1;
Xchange=1;

If (DeltaX < 0 )
{
XChange = -1 ;
DeltaX = -DeltaX ;
}




If (DeltaY < 0 )
{
YChange = -1;
DeltaY = -DeltaY ;
}




accm_error = 0;
i = 0 ;

If (DeltaX < DeltaY)
{
Line_Length = DeltaY + 1;

while (i < Line_Length)
{
Y =Y + YChange ;
accm_error = accm_error + DeltaX ;

IF (accm_error > DeltaY)
{
X = X + XChange ;
accm_error = accm_error - DeltaY ;

}

i = i + 1 ;
plot(x,y,set);
}
}
else
{
Line_Length = DeltaX + 1;

While (i < Line_Length)
{
X =X + XChange ;
accm_error = accm_error + DeltaY;

If (accm_error > DeltaX)
{
Y = Y + YChange;
accm_error= accm_error - DeltaX ;
}

i = i + 1;
plot(x,y,set);
}
}




enable_interrupts(GLOBAL);
}
___________________________
This message was ported from CCS's old forum
Original Post ID: 9022
john lee
Guest







Re: Bresenham algorithm in a Pic 16c73A
PostPosted: Sat Nov 16, 2002 8:30 am     Reply with quote

:=This will draw a line between cartesian pts (x1,y1) (x2,y2)
:=plot (x,y,set) is a routine to turn on or off a pixel depending on the value of set.
:=Bresenham used the finite difference calculus to gain speed and avoid multipication. I have circle algorithms if you are interested
:=
:=
:=
:=void line(long x1,long y1,long x2,long y2, int set)
:={
:=long i,line_length,x,y;
:=signed long deltax,deltay,accm_error;
:=signed int xchange,ychange;
:=// bresenham algorithm for lines
:=disable_interrupts(GLOBAL);
:= X = x1 ;
:= Y = y1;
:=
:=DeltaX = x2 - x1;
:=DeltaY = y2 - y1 ;
:=Ychange=1;
:=Xchange=1;
:=
:=If (DeltaX < 0 )
:= {
:= XChange = -1 ;
:= DeltaX = -DeltaX ;
:= }
:=
:=
:=
:=
:=If (DeltaY < 0 )
:= {
:= YChange = -1;
:= DeltaY = -DeltaY ;
:= }
:=
:=
:=
:=
:=accm_error = 0;
:=i = 0 ;
:=
:=If (DeltaX < DeltaY)
:= {
:= Line_Length = DeltaY + 1;
:=
:= while (i < Line_Length)
:= {
:= Y =Y + YChange ;
:= accm_error = accm_error + DeltaX ;
:=
:= IF (accm_error > DeltaY)
:= {
:= X = X + XChange ;
:= accm_error = accm_error - DeltaY ;
:=
:= }
:=
:= i = i + 1 ;
:= plot(x,y,set);
:= }
:= }
:=else
:= {
:= Line_Length = DeltaX + 1;
:=
:= While (i < Line_Length)
:= {
:= X =X + XChange ;
:= accm_error = accm_error + DeltaY;
:=
:= If (accm_error > DeltaX)
:= {
:= Y = Y + YChange;
:= accm_error= accm_error - DeltaX ;
:= }
:=
:= i = i + 1;
:= plot(x,y,set);
:= }
:= }
:=
:=
:=
:=
:=enable_interrupts(GLOBAL);
:=}

Hi, Doug.
Many thanks for your sample, I used a very watered-down version of the bresenham algorithm ,for octant(0) it looks like:
long int x,y,x_count; //x & y are the abs numbers of pulses to output,x_count is the current count in x//

int v_min,v_max,ramp_rate //parameters to the move func
//the move func generates 2 pulse trains to drive 2 machine axes//
//in a co-ordinated move with velocity ramps//

bres_line(x,y) //case for octant(0),where X>=Y
{
x_count=0 //init x_count
E=(2*y)-(2*x); //inital error(doubled to avoid floats)//
do
{
if E<0 then E=E+(2*y);
else E=E+(2*y)-(2*x);
pulse_x(); //pulse the major axis,X
if E>=0 then pulse_y();//pulse y if test true
x_count=x_count++; //increment x
}
while(x_count<=x);
}
//pulse_x()&pulse_y() are funcs to pulse the axes high for
//10usec. The move() func simply co-ordinates it all, and uses
the rtcc and ccp1 to generate pulses at a variable period, period is updated during the ccp1 interrupt. Works not bad, but
in the real version, I am counting x_pulses on the int_ext,and appear to be getting glitches in the write to the ccp1.
Basically I have been lazy in debugging it, and thought,"Why re-invent the wheel?" Someone somewhere has it all-singing already.
Many thanks for the code, would like to see your circles?
Regards,
John Lee.
___________________________
This message was ported from CCS's old forum
Original Post ID: 9033
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group