-
Notifications
You must be signed in to change notification settings - Fork 0
/
printer_driver.c
266 lines (225 loc) · 8.17 KB
/
printer_driver.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
/* File: printer.c
* =-=-=-=-=-=-=-=
* @author Gui Suranyi, Winter 2024
* ...
*/
// Library Imports
#include "gl.h"
#include "gpio.h"
#include "gpio_extra.h"
#include "gpio_interrupt.h"
#include "interrupts.h"
#include "printf.h"
#include "ringbuffer.h"
#include "uart.h"
#include "malloc.h"
#include "hstimer.h"
// Project Imports
#include "printer_driver.h"
static const gpio_id_t X_STEP_PIN = GPIO_PB4, Y_STEP_PIN = GPIO_PB3, Z_STEP_PIN = GPIO_PB2;
static const gpio_id_t X_DIR_PIN = GPIO_PD17, Y_DIR_PIN = GPIO_PB6, Z_DIR_PIN = GPIO_PB12;
static const gpio_id_t X_LIMIT_PIN = GPIO_PC0, Y_LIMIT_PIN = GPIO_PC1, Z_LIMIT_PIN = GPIO_PB11;
static const gpio_id_t VACUUM_PIN = GPIO_PB10;
static volatile int X_STEP_PIN_State, X_Steps, X_Current_Steps, X_Target_Interval, X_Current_Interval, X_Intermediary_Interval;
static volatile int Y_STEP_PIN_State, Y_Steps, Y_Current_Steps, Y_Target_Interval, Y_Current_Interval, Y_Intermediary_Interval;
static volatile int Z_STEP_PIN_State, Z_Steps, Z_Current_Steps, Z_Target_Interval, Z_Current_Interval, Z_Intermediary_Interval;
static volatile int X_Position, Y_Position, Z_Position;
static volatile unsigned int X_Zero_Reference = 45000, Y_Zero_Reference = 3000;
unsigned int find_max (unsigned int x, unsigned int y, unsigned int z) {
if (x == 0 && y == 0 && z == 0){
return 0;
}
else if (x >= y && x > z){
return 1;
}
else if (y > x && y >= z){
return 2;
}
else {
return 3;
}
}
static void steppers(uintptr_t pc, void *aux_data) {
hstimer_interrupt_clear(HSTIMER0);
//movement for X stepper motor
if (X_Steps > 0){
X_Current_Interval ++;
if (X_Current_Interval == X_Intermediary_Interval){
if (X_STEP_PIN_State == 1){
gpio_write(X_STEP_PIN, 0);
X_STEP_PIN_State = 0;
X_Steps --;
if (X_Intermediary_Interval > X_Target_Interval && X_Steps > 100){
X_Intermediary_Interval --;
}
else {
X_Intermediary_Interval ++;
}
}
else {
gpio_write(X_STEP_PIN, 1);
X_STEP_PIN_State = 1;
}
X_Current_Interval = 0;
}
}
//movement for Y stepper motor
if (Y_Steps > 0){
Y_Current_Interval ++;
if (Y_Current_Interval == Y_Intermediary_Interval){
if (Y_STEP_PIN_State == 1){
gpio_write(Y_STEP_PIN, 0);
Y_STEP_PIN_State = 0;
Y_Steps --;
if (Y_Intermediary_Interval > Y_Target_Interval && Y_Steps > 100){
Y_Intermediary_Interval --;
}
else {
Y_Intermediary_Interval ++;
}
}
else {
gpio_write(Y_STEP_PIN, 1);
Y_STEP_PIN_State = 1;
}
Y_Current_Interval = 0;
}
}
//movement for Z stepper motor
if (Z_Steps > 0){
Z_Current_Interval ++;
if (Z_Current_Interval == Z_Intermediary_Interval){
if (Z_STEP_PIN_State == 1){
gpio_write(Z_STEP_PIN, 0);
Z_STEP_PIN_State = 0;
Z_Steps --;
if (Z_Intermediary_Interval > Z_Target_Interval && Z_Steps > 100){
Z_Intermediary_Interval --;
}
else {
Z_Intermediary_Interval ++;
}
}
else {
gpio_write(Z_STEP_PIN, 1);
Z_STEP_PIN_State = 1;
}
Z_Current_Interval = 0;
}
}
}
void configure_steppers(void) {
// armtimer is intialized to number of usecs between events
gpio_set_output(X_STEP_PIN);
gpio_set_output(Y_STEP_PIN);
gpio_set_output(Z_STEP_PIN);
gpio_set_output(X_DIR_PIN);
gpio_set_output(Y_DIR_PIN);
gpio_set_output(Z_DIR_PIN);
hstimer_init(HSTIMER0, 10);
hstimer_enable(HSTIMER0); // enable timer itself
interrupts_register_handler(INTERRUPT_SOURCE_HSTIMER0, steppers, NULL);
interrupts_enable_source(INTERRUPT_SOURCE_HSTIMER0);
}
void configure_limit_switches(void){
gpio_set_input (X_LIMIT_PIN);
gpio_set_pullup(X_LIMIT_PIN);
gpio_set_input (Y_LIMIT_PIN);
gpio_set_pullup(Y_LIMIT_PIN);
gpio_set_input (Z_LIMIT_PIN);
gpio_set_pullup(Z_LIMIT_PIN);
}
void configure_vacuum (void) {
gpio_set_output(VACUUM_PIN);
}
void activate_vacuum (void) {
gpio_write(VACUUM_PIN, 1);
}
void deactivate_vacuum (void) {
gpio_write(VACUUM_PIN, 0);
}
void move_steppers (int x, int y, int z, int velocity){
// If the desired x move, is less than 0, we need to flip the Dir pin output, and get the absolute of the steps
if (x < 0){
gpio_write(X_DIR_PIN, 0);
X_Steps = -x;
}
else {
gpio_write(X_DIR_PIN, 1);
X_Steps = x;
}
if (y < 0){
gpio_write(Y_DIR_PIN, 0);
Y_Steps = -y;
}
else {
gpio_write(Y_DIR_PIN, 1);
Y_Steps = y;
}
if (z < 0){
gpio_write(Z_DIR_PIN, 0);
Z_Steps = -z;
}
else {
gpio_write(Z_DIR_PIN, 1);
Z_Steps = z;
}
unsigned int largestMove = find_max(X_Steps, Y_Steps, Z_Steps);
X_Intermediary_Interval = 150; // STARTING SPEED FOR THE STEPPERS
Y_Intermediary_Interval = 150; // LOWER SPEED = MORE TORQUE
Z_Intermediary_Interval = 150;
X_Target_Interval = velocity;
Y_Target_Interval = velocity;
Z_Target_Interval = velocity;
}
void home_steppers(void){
while (gpio_read(Z_LIMIT_PIN) == 1){
gpio_write(Z_LIMIT_PIN, 0);
Z_Steps = 101;
Z_Target_Interval = 10;
Z_Intermediary_Interval = 20;
}
while (Z_Steps != 0) {}
while (gpio_read(Y_LIMIT_PIN) == 1){
gpio_write(Y_DIR_PIN, 0);
Y_Steps = 101;
Y_Target_Interval = 10;
Y_Intermediary_Interval = 20;
}
while (Y_Steps != 0) {}
while (gpio_read(X_LIMIT_PIN) == 1){
gpio_write(X_DIR_PIN, 0);
X_Steps = 101;
X_Target_Interval = 10;
X_Intermediary_Interval = 20;
}
while (X_Steps != 0) {}
}
void move_to(int X_Desired_Position, int Y_Desired_Position, int Z_Desired_Position, int speed){
//calculate how much each motor needs to move
int X_move = X_Desired_Position - X_Position;
int Y_move = Y_Desired_Position - Y_Position;
int Z_move = Z_Desired_Position - Z_Position;
// update the current position for each of the axis
X_Position = X_Desired_Position;
Y_Position = Y_Desired_Position;
Z_Position = Z_Desired_Position;
//move the stepper to the desired position
printf("X_move: %d, Y_move: %d, Z_move: %d, %d\n", X_move, Y_move, Z_move, ((X_move * X_move) + (Y_move * Y_move) + (Z_move * Z_move)));
move_steppers(X_move, Y_move, Z_move, speed);
while (X_Steps != 0 || Y_Steps != 0 || Z_Steps != 0) {}
}
void pick_and_place(int X_End_Position, int Y_End_Position, coordinate color){
int Brick_X_Coordinate = color.x;
int Brick_Y_Coordinate = color.y;
unsigned int X_Coordinate_End_Position = X_End_Position * 3200 + X_Zero_Reference;
unsigned int Y_Coordinate_End_Position = Y_End_Position * 3200 + Y_Zero_Reference;
move_to(Brick_X_Coordinate, Brick_Y_Coordinate, 3000, 7); // First go to the position where the brick of the specified color is located
move_to(Brick_X_Coordinate, Brick_Y_Coordinate, 8000, 10); // Then lower the pick and place nozzle
activate_vacuum(); // Turn the vacuum on
move_to(Brick_X_Coordinate, Brick_Y_Coordinate, 3000, 10); // Go back up
move_to(X_Coordinate_End_Position, Y_Coordinate_End_Position, 3000, 7); // Go to the end position of the brick
move_to(X_Coordinate_End_Position, Y_Coordinate_End_Position, 9000, 10); // Place the part
deactivate_vacuum(); // Turn the vacuum off
move_to(X_Coordinate_End_Position, Y_Coordinate_End_Position, 3000, 10); // Raise the pick and place arm
}