Commits

Jaroslav Beran  committed 6ba513e

Limits

  • Participants
  • Parent commits 9ff1816

Comments (0)

Files changed (3)

 static void text_demo(PRINTER *prn);
 static void triangle_demo(PRINTER *prn);
 static void draw_triangle_fragment(PRINTER *prn, D_POSITION vertex, double len, double distance, double angle);
+static void limits_demo(PRINTER *prn);
 static void hpgl_demo(PRINTER *prn);
 
 
 
 static int show_menu(PRINTER *prn) {
 	printf("PlotterController\n");
-	printf("Build 20140216\n");
+	printf("Build 20140220\n");
 	printf("---------------------------\n\n");
 
 	printf("1) Test page\n");
 	printf("3) Circles demo\n");
 	printf("4) Text demo\n");
 	printf("5) Triangle demo\n");
-	printf("6) HPGL demo\n");
+	printf("6) Limits demo\n");
+	printf("7) HPGL demo\n");
 	printf("0) Exit\n");
 
 	printf("\n");
 				break;
 		case '5' :	triangle_demo(prn);
 				break;
-		case '6' :	hpgl_demo(prn);
+		case '6' :	limits_demo(prn);
+				break;
+		case '7' :	hpgl_demo(prn);
 				break;
 	}
 
 	}
 }
 
+static void limits_demo(PRINTER *prn) {
+	pr_init(prn);
+	POSITION paper = pr_get_max_position(prn);
+
+	xy_va(prn, paper.x, 0);
+	xy_va(prn, paper.x, paper.y);
+	xy_va(prn, 0, paper.y);
+	xy_va(prn, 0, 0);
+
+	xy_ma(prn, paper.x / 2, paper.y / 2);
+	int i;
+	for (i = 1; i < 6; i++) {
+		xy_cr(prn, 300 * i);
+	}
+
+	xy_hm(prn);
+}
+
 static void hpgl_demo(PRINTER *prn) {
 	char file_name[100];
 	printf("Enter HPGL file name: ");

File src/printer.c

 #define PEN_BIT 2
 #define STEP_BIT 3
 #define XY_BIT 1		/* L = CART, H = PAPER */
-#define DIRECTION_BIT 0	/* L = TO LEFT (FORWARD), H = TO RIGHT (BACK) */
+#define DIRECTION_BIT 0		/* L = TO LEFT (FORWARD), H = TO RIGHT (BACK) */
 #define READY_BIT 4		/* L = READY, H = NOT READY */
 
 #define MAX_X 2600
 
 #define check_bit(var,pos) ((var) & (1<<(pos)))
 
-/* 
+/*
  *	Speed value is sleep interval in ms
  *	There are 10 values (0 the slowes 9 the fasts)
  */
 static speed[] = {2600,2400,2200,2000,1800,1600,1400,1200,1000,800};
 
+static void dirty_pen(PRINTER *p, int value);
 static int is_ready(PRINTER *p);
 static void step(PRINTER *p, int repeat);
 static void dirty_step(PRINTER *p);
 static void switch_x_y(PRINTER *p, int value);
 static void switch_direction(PRINTER *p, int value);
+static int check_cross_limits(PRINTER *p);
+static void sync_virt_curr_position(PRINTER *p);
 static void print_port_status(PRINTER *p);
 static void set_bit(DATA *data, int pos, int value);
 
+
 /*
 *	Create printer instance
 */
 	int fd;
 
 	if ((fd = open_parport(device_name)) == 0) {
-        return NULL;
-    }
+		return NULL;
+	}
 
 	PRINTER *result = (PRINTER *) malloc(sizeof(PRINTER));
 
 	result->origin_position.y = 0;
 	result->moving_buffer.x = 0;
 	result->moving_buffer.y = 0;
+	result->virtual_position.x = 0;
+	result->virtual_position.y = 0;
+	result->virtual_pen = 0;
+	result->out_of_limits = 0;
 	result->data = 0;
 	result->velocity = 8;
 
 	return result;
 }
 
+
 /*
 *	Close printer instance
 */
 	}
 }
 
+
 /*
 *	Init printer
 */
 	}
 }
 
+
 /*
-*       Returns max position;
+*	Returns max position;
 */
 POSITION pr_get_max_position(PRINTER *p) {
 	return p->max_position;
 }
 
+
 /*
 *	Returns current position;
 */
 POSITION pr_get_current_position(PRINTER *p) {
 	POSITION result;
-	result.x =  p->curr_position.x;
-	result.y =  p->curr_position.y;
+	result.x =  p->virtual_position.x;
+	result.y =  p->virtual_position.y;
 	result.x -= p->origin_position.x;
 	result.y -= p->origin_position.y;
 	result.x += p->moving_buffer.x; 
 	return result;
 }
 
+
 /*
 *	Returns origin position;
 */
 	return p->origin_position;
 }
 
+
 /*
 *	Set origin position;
 */
 	p->origin_position.y = y;
 }
 
+
 /*
 *	Returns moving buffer;
 */
 	return p->moving_buffer;
 }
 
+
 /*
 *	Set moving buffer;
 */
 	p->moving_buffer.y = y;
 }
 
+
 /*
 *	Set velocity (0-9)
 */
 	}
 }
 
+
 /*
 *	Set pen
 */
 void pr_pen(PRINTER *p, int value) {
+	if (p->virtual_pen != value) {
+		p->virtual_pen = value;
+		if (!p->out_of_limits) dirty_pen(p, value);
+	}
+}
+
+
+/*
+*	Set dirty pen
+*/
+static void dirty_pen(PRINTER *p, int value) {
 	set_bit(&(p->data), PEN_BIT, value);
 	write_data(p->parport_fd, p->data);
 	USLEEP(speed[p->velocity] * 10);
 }
 
+
 /*
 *	Move
 *	xy		0 = CART (Y), 1 = PAPER (X)
 	step(p, repeat);
 }
 
+
 /*
 *	Is ready test
 */
 	return (check_bit(data, READY_BIT) == 0);
 }
 
+
 /*
 *	Do step
 */
 static void step(PRINTER *p, int repeat) {
+	int step_dir = (check_bit(p->data, DIRECTION_BIT) == 0) ? -1 : 1;
 	int i;
 	for (i = 0; i < repeat; i++) {
-		dirty_step(p);
 		
 		if (check_bit(p->data, XY_BIT) == 0) {
-			if ((check_bit(p->data, DIRECTION_BIT) == 0)) {
-				(p->curr_position.y)--;
-			} else {
-				(p->curr_position.y)++;
+			p->virtual_position.y += step_dir;
+			if (!check_cross_limits(p) && !p->out_of_limits) {
+				p->curr_position.y += step_dir;
+				dirty_step(p);
 			}
 		} else {
-			if ((check_bit(p->data, DIRECTION_BIT) == 0)) {
-				(p->curr_position.x)--;
-			} else {
-				(p->curr_position.x)++;
+			p->virtual_position.x += step_dir;
+			if (!check_cross_limits(p) && !p->out_of_limits) {
+				p->curr_position.x += step_dir;
+				dirty_step(p);
 			}
 		}
 	}
 }
 
+
+/*
+*	Perform dirty step
+*/
 static void dirty_step(PRINTER *p) {
 	set_bit(&(p->data), STEP_BIT, 0);
 	write_data(p->parport_fd, p->data);
 	set_bit(&(p->data), XY_BIT, value);
 }
 
+
 /*
 *	Set +/-
 */
 
 
 /*
+*	Check cross limits
+*/
+static int check_cross_limits(PRINTER *p) {
+	int previous = p->out_of_limits;
+	int current = (p->virtual_position.x > p->max_position.x) 
+			|| (p->virtual_position.x < 0)
+			|| (p->virtual_position.y > p->max_position.y)
+			|| (p->virtual_position.y < 0);
+
+	if (previous < current) {
+		p->out_of_limits = 1;
+		dirty_pen(p, 0);
+		return 1;
+	}
+
+	if (previous > current) {
+		p->out_of_limits = 0;
+		sync_virt_curr_position(p);
+		return 1;
+	}
+
+	return 0;
+}
+
+
+/*
+*	Move
+*	xy		0 = CART (Y), 1 = PAPER (X)
+*	direction	0 = TO LEFT (FORWARD), 1 = TO RIGHT (BACK)
+*	repeat		1 step = 0.1 mm
+*/
+static void sync_virt_curr_position(PRINTER *p) {
+	DATA data = p->data;
+	int i;
+
+	if (p->curr_position.x != p->virtual_position.x) {
+		switch_x_y(p, 1);
+		switch_direction(p, (p->curr_position.x < p->virtual_position.x));
+		for (i = 0; i < abs(p->virtual_position.x - p->curr_position.x); i++) {
+			dirty_step(p);
+		}
+		p->curr_position.x = p->virtual_position.x;
+	}
+
+	if (p->curr_position.y != p->virtual_position.y) {
+		switch_x_y(p, 0);
+		switch_direction(p, (p->curr_position.y < p->virtual_position.y));
+		for (i = 0; i < abs(p->virtual_position.y - p->curr_position.y); i++) {
+			dirty_step(p);
+		}
+		p->curr_position.y = p->virtual_position.y;
+	}
+
+	p->data = data;
+	dirty_pen(p, p->virtual_pen);
+}
+
+
+/*
 *	Print status
 */
 static void print_port_status(PRINTER *p) {
 	printf("----------\n");
 }
 
+
 /*
 *	Set bit
 */

File src/printer.h

 	POSITION	curr_position;
 	POSITION	origin_position;
 	POSITION	moving_buffer;
+	POSITION	virtual_position;
+	int		virtual_pen;
+	int		out_of_limits;
 	DATA		data;
 	int		velocity;
 } PRINTER;
 extern void pr_init(PRINTER *p);
 
 /*
-*       Returns max position;
+*	Returns max position;
 */
 extern POSITION pr_get_max_position(PRINTER *p);