-
Notifications
You must be signed in to change notification settings - Fork 1
/
main.c
245 lines (191 loc) · 6.34 KB
/
main.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
#include <avr/io.h>
#include <stdlib.h>
#include "USBtoSerial.h"
#include <util/delay.h>
#include "TM1001A.h"
#include "motors.h"
#include "misc.h"
#include "pins.h"
#include "plate.h"
#define UM_PER_ROUND 1000 //micrometers per axis revolution
#define STEPS_PER_ROUND 24 //steps per axis revolution
int32_t steps_to_um (int32_t steps){
return steps*UM_PER_ROUND/STEPS_PER_ROUND;
}
int32_t um_to_steps (int32_t um){
return um*STEPS_PER_ROUND/UM_PER_ROUND;
}
void print_steps_in_mm(int32_t steps) {
int32_t um = steps_to_um(steps);
uint16_t predot = abs(um/1000);
uint16_t postdot = abs(um%1000);
uart_print_sign(steps);
uart_print_number(predot,3);
uart_putc('.');
uart_print_number_wlzeros(postdot,3);
}
void pos_report(void){
uart_puts("x_pos: ");
print_steps_in_mm(get_plate_pos_x());
uart_puts(" y_pos: ");
print_steps_in_mm(get_plate_pos_y());
uart_puts("\r\n");
}
typedef enum {POSITION, GOTO, MOVEREL, SETZERO} action_t;
void parse_command(void){
static char cmdbuffer[32];
static char numbuffer[16];
static uint16_t predot = 0,postdot = 0;
static uint8_t cmdPos, curCmdLen, num_start = 0, nums_found = 0;
uint8_t axis=0;
action_t action = POSITION;
int8_t num_sign = 1;
char byte;
/* Load the next byte from the USART transmit buffer into the USART */
uint16_t pop = uart_getc();
if(!(pop == EMPTY)){
byte = (char) pop;
if (byte == '\r' || byte == '\n') {// end of command, evaluate cemmand!
uart_puts("\r\n");
cmdbuffer[cmdPos] = '\0'; // terminate new command string
curCmdLen = cmdPos;
cmdPos = 0;
if (cmdbuffer[0] == 'g' || cmdbuffer[0] == 'G') { // goto command
action = GOTO;
} else if ( cmdbuffer[0] == 'm' || cmdbuffer[0] == 'M') {
action = MOVEREL;
} else if ( cmdbuffer[0] == 'z' || cmdbuffer[0] == 'Z' ) {
action = SETZERO;
} else {
action = POSITION;
}
if (cmdbuffer[1] == 'x' || cmdbuffer[1] == 'X') {
axis = X;
} else if (cmdbuffer[1] == 'y' || cmdbuffer[1] == 'Y') {
axis = Y;
}
// if you expect coordinate, parse number!
if (action == GOTO || action == MOVEREL){
predot = 0;
postdot = 0;
num_sign = 1;
num_start = 0;
nums_found = 0;
for (uint8_t i=2; i<=curCmdLen; i++) {
if ( num_start == 0 && cmdbuffer[i] == '-' ) { // if you find a minus before
// you find a digit, it's a negative number
num_sign = -1;
}
if ( cmdbuffer[i] >= 48 && cmdbuffer[i] <= 57 ){ // is it a number?
if ( num_start == 0) { // this is the first digit in the string
num_start = i;
}
} else { // no digit!
if ( num_start != 0) { // digits have been found before
strncpy(numbuffer,cmdbuffer+num_start,i-num_start); // copy number found to
// numbuffer
numbuffer[i-num_start] = '\0'; // make sure it's always a terminated string
nums_found++;
if(nums_found == 1) { // its the predot digits
predot = atoi(numbuffer);
} else { // its the postdot digits
uint8_t postdotlen = i-num_start;
if (postdotlen < 3){ // if too small ,fill with zeros
for( uint8_t j = postdotlen; j <=2; j++) {
numbuffer[j] = '0';
}
}
// crop the number to three post dot digits
numbuffer[3] = '\0';
postdot = atoi(numbuffer);
}
num_start = 0;
}
}
}
}
int32_t steps = 0,dest=0;
switch (action) {
case GOTO:
uart_puts("GOTO ");
uart_putc(88+axis);// x or y
uart_putc(' ');
uart_print_sign(num_sign);
uart_print_number(predot,3);
uart_putc('.');
uart_print_number_wlzeros(postdot,3);
uart_puts("\r\n");
dest = um_to_steps(num_sign*(((int32_t) predot) *1000 + ((int32_t) postdot)));
if (axis == X) {
set_target_plate_pos_x(dest);
} else if (axis == Y) {
set_target_plate_pos_y(dest);
}
break;
case MOVEREL:
uart_puts("MOVE ");
uart_putc(88+axis);// x or y
uart_putc(' ');
uart_print_sign(num_sign);
uart_print_number(predot,3);
uart_putc('.');
uart_print_number_wlzeros(postdot,3);
uart_puts("\r\n");
steps = um_to_steps(num_sign*(((int32_t) predot) *1000 + ((int32_t) postdot)));
if (axis == X) {
set_target_plate_pos_x(get_target_plate_pos_x()+steps);
} else if (axis == Y) {
set_target_plate_pos_y(get_target_plate_pos_y()+steps);
}
break;
case SETZERO:
set_plate_pos_x(0);
set_plate_pos_y(0);
set_target_plate_pos_x(0);
set_target_plate_pos_y(0);
pos_report();
break;
case POSITION:
pos_report();
break;
}
} else { // queue command
if( cmdPos == 0 ){
uart_puts("\r\n$ ");
}
if( byte == 8 ){ // backspace
cmdPos--;
} else {
cmdbuffer[cmdPos++] = byte;
}
uart_putc(byte);
}
}
}
int main(void){
init_motors();
init_leds();
init_sw();
SetupHardware(); //initializes all USB stuff
touchpad_init(); // you need to call this to setup the I/O pin!
_delay_ms(500);
sei();
while (1) {
set_led0(sw0_state());
set_led1(sw1_state());
set_led2(sw2_state());
Usb2SerialTask();
parse_command(); // read data from virtual comport
touchpad_read(); // read data from touchpad
if(sw0_state()){ // if left switch is active (enable x-axis)
inc_target_plate_pos_x(-delta_x());
}
if(sw1_state()){ // if middle switch is active (enable y-axis)
inc_target_plate_pos_y(-delta_y());
}
plate_task();
if(plate_ready()){
pos_report();
}
}
} // end of main