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 | #include <stdio.h>
|
39 | #include <stdlib.h>
|
40 | #include <math.h>
|
41 | #include <string.h>
|
42 |
|
43 | #include "pico/stdlib.h"
|
44 | #include "pico/multicore.h"
|
45 |
|
46 | #include "hardware/pwm.h"
|
47 |
|
48 | #include "vga_graphics.h"
|
49 | #include "pt_cornell_rp2040_v1.h"
|
50 |
|
51 |
|
52 | typedef signed int fix15 ;
|
53 | #define multfix15(a,b) ((fix15)((((signed long long)(a))*((signed long long)(b)))>>15))
|
54 | #define float2fix15(a) ((fix15)((a)*32768.0))
|
55 | #define fix2float15(a) ((float)(a)/32768.0)
|
56 | #define absfix15(a) abs(a)
|
57 | #define int2fix15(a) ((fix15)(a << 15))
|
58 | #define fix2int15(a) ((int)(a >> 15))
|
59 | #define char2fix15(a) (fix15)(((fix15)(a)) << 15)
|
60 | #define divfix(a,b) (fix15)( (((signed long long)(a)) << 15) / (b))
|
61 | #define min(a,b) ((a<b) ? a:b)
|
62 | #define max(a,b) ((a<b) ? b:a)
|
63 | #define abs(a) ((a>0) ? a:-a)
|
64 | #define SIGN(x) ((x > 0) - (x < 0))
|
65 | #define PI 3.14159
|
66 |
|
67 |
|
68 | static struct pt_sem vga_semaphore;
|
69 | const int dirPin_rotation = 3;
|
70 | const int stepPin_rotation = 2;
|
71 | const int dirPin_lift = 15;
|
72 | const int stepPin_lift = 14;
|
73 | int stepsPerRevolution;
|
74 | float degree = 0.0;
|
75 | int redius = 100;
|
76 | int rotate_flag = 0;
|
77 | #define FRAME_RATE 16667
|
78 | #define BASE_KEYPAD_PIN 7
|
79 | #define KEYROWS 4
|
80 | #define NUMKEYS 12
|
81 | static int idx;
|
82 | static int old_idx;
|
83 | unsigned int keycodes[12] = { 0x28, 0x11, 0x21, 0x41, 0x12,
|
84 | 0x22, 0x42, 0x14, 0x24, 0x44,
|
85 | 0x18, 0x48} ;
|
86 | unsigned int scancodes[4] = { 0x01, 0x02, 0x04, 0x08} ;
|
87 | unsigned int button = 0x70 ;
|
88 | int lift = 0;
|
89 | int page = 0;
|
90 | int stop = 0;
|
91 | int manual_auto = 0;
|
92 | int auto_index = 0;
|
93 | int temp_step = 0;
|
94 | int temp_step2 = 0;
|
95 | int temp_step3 = 0;
|
96 | int interval = 0;
|
97 | int interval2 = 0;
|
98 | static int new_x ;
|
99 | static int new_y ;
|
100 | char deg[50];
|
101 | char temp[50];
|
102 | char temp1[50];
|
103 | char temp2[50];
|
104 |
|
105 |
|
106 | void on_pwm_wrap() {
|
107 |
|
108 | pwm_clear_irq(pwm_gpio_to_slice_num(5));
|
109 |
|
110 | PT_SEM_SIGNAL(pt, &vga_semaphore);
|
111 | }
|
112 |
|
113 | void draw_UI(){
|
114 | fillRect(440, 200, 200, 280, BLACK);
|
115 | drawRect(440, 200, 200, 280, WHITE);
|
116 | setCursor(450, 210);
|
117 | setTextColor2(WHITE, BLACK);
|
118 | switch (page){
|
119 | case 0:
|
120 | writeString("Main Page");
|
121 | setCursor(450, 230);
|
122 | writeString("1. Manual");
|
123 | setCursor(450, 250);
|
124 | writeString("2. Auto");
|
125 | break;
|
126 | case 1:
|
127 | writeString("Manual Page");
|
128 | setCursor(450, 230);
|
129 | writeString("1. Rotation");
|
130 | setCursor(450, 250);
|
131 | writeString("2. Lift");
|
132 | setCursor(450, 270);
|
133 | writeString("#. Back");
|
134 | break;
|
135 | case 11:
|
136 | writeString("Manual Rotation Page");
|
137 | setCursor(450, 230);
|
138 | writeString("0-9. Input");
|
139 | setCursor(450, 250);
|
140 | writeString("*. Confirm");
|
141 | setCursor(450, 270);
|
142 | writeString("#. Back");
|
143 | setCursor(450, 290);
|
144 | writeString(temp);
|
145 | break;
|
146 | case 12:
|
147 | writeString("Manual Lift Page");
|
148 | setCursor(450, 230);
|
149 | writeString("2. Up");
|
150 | setCursor(450, 250);
|
151 | writeString("5. Down");
|
152 | setCursor(450, 270);
|
153 | writeString("3. Up 1cm");
|
154 | setCursor(450, 290);
|
155 | writeString("6. Down 1cm");
|
156 | setCursor(450, 310);
|
157 | writeString("#. Back");
|
158 | break;
|
159 | case 2:
|
160 | writeString("Auto Page");
|
161 | switch (auto_index){
|
162 | case 0:
|
163 | setCursor(450, 230);
|
164 | writeString("Rotation degree:");
|
165 | setCursor(450, 250);
|
166 | writeString("0-9. Input");
|
167 | setCursor(450, 270);
|
168 | writeString("*. Confirm");
|
169 | setCursor(450, 290);
|
170 | writeString("#. Back to main");
|
171 | setCursor(450, 310);
|
172 | writeString(temp);
|
173 | break;
|
174 | case 1:
|
175 | setCursor(450, 230);
|
176 | writeString("Rotation interval in seconds:");
|
177 | setCursor(450, 250);
|
178 | writeString("0-9. Input");
|
179 | setCursor(450, 270);
|
180 | writeString("*. Confirm");
|
181 | setCursor(450, 290);
|
182 | writeString("#. Back to main");
|
183 | setCursor(450, 310);
|
184 | writeString(temp);
|
185 | setCursor(450, 330);
|
186 | writeString(temp1);
|
187 | break;
|
188 | case 2:
|
189 | setCursor(450, 230);
|
190 | writeString("Manual Lift Control");
|
191 | setCursor(450, 250);
|
192 | writeString("2. Up");
|
193 | setCursor(450, 270);
|
194 | writeString("5. Down");
|
195 | setCursor(450, 290);
|
196 | writeString("*. Confirm");
|
197 | setCursor(450, 310);
|
198 | writeString("#. Back to main");
|
199 | setCursor(450, 330);
|
200 | writeString(temp);
|
201 | setCursor(450, 350);
|
202 | writeString(temp1);
|
203 | break;
|
204 | case 3:
|
205 | setCursor(450, 230);
|
206 | writeString("Lift interval in cm:");
|
207 | setCursor(450, 250);
|
208 | writeString("0-9. Input");
|
209 | setCursor(450, 270);
|
210 | writeString("*. Confirm");
|
211 | setCursor(450, 290);
|
212 | writeString("#. Back to main");
|
213 | setCursor(450, 310);
|
214 | writeString(temp);
|
215 | setCursor(450, 330);
|
216 | writeString(temp1);
|
217 | setCursor(450, 350);
|
218 | writeString(temp2);
|
219 | break;
|
220 | }
|
221 | break;
|
222 | }
|
223 | }
|
224 |
|
225 | void detect_keypad(){
|
226 |
|
227 | static uint32_t keypad ;
|
228 | for (idx=0; idx<KEYROWS; idx++) {
|
229 |
|
230 | gpio_put_masked((0xF << BASE_KEYPAD_PIN),
|
231 | (scancodes[idx] << BASE_KEYPAD_PIN)) ;
|
232 |
|
233 | sleep_us(1) ;
|
234 |
|
235 | keypad = ((gpio_get_all() >> BASE_KEYPAD_PIN) & 0x7F) ;
|
236 |
|
237 | if (keypad & button) break ;
|
238 | }
|
239 |
|
240 | if (keypad & button) {
|
241 |
|
242 | for (idx=0; idx<NUMKEYS; idx++) {
|
243 | if (keypad == keycodes[idx]) break ;
|
244 | }
|
245 |
|
246 | if (idx==NUMKEYS) (idx = -1) ;
|
247 | }
|
248 |
|
249 | else (idx=-1) ;
|
250 | }
|
251 |
|
252 | void draw_rotation_platform(){
|
253 |
|
254 | drawCircle(320, 240, redius, WHITE);
|
255 | drawLine(320, 240, new_x, new_y, BLACK);
|
256 | new_x = 320 + redius * sin(-degree*PI/180);
|
257 | new_y = 240 + redius * cos(-degree*PI/180);
|
258 | drawLine(320, 240, new_x, new_y, WHITE);
|
259 | }
|
260 |
|
261 | void draw_rotation_text(){
|
262 | setCursor(250, 400);
|
263 | setTextColor2(BLACK, BLACK);
|
264 | writeString(deg);
|
265 | setCursor(250, 400);
|
266 | setTextColor2(WHITE, BLACK);
|
267 | sprintf(deg, "%s%.2f", "Current Degree is ", degree);
|
268 | writeString(deg);
|
269 | }
|
270 |
|
271 |
|
272 | static PT_THREAD (protothread_vga(struct pt *pt))
|
273 | {
|
274 |
|
275 | PT_BEGIN(pt) ;
|
276 |
|
277 | static int begin_time ;
|
278 | static int spare_time ;
|
279 | setTextSize(1);
|
280 |
|
281 | sprintf(temp, "%s%.2f", "Current Degree is ", temp_step*1.8);
|
282 | draw_rotation_platform();
|
283 | draw_rotation_text();
|
284 | draw_UI();
|
285 |
|
286 | while(1) {
|
287 |
|
288 | begin_time = time_us_32();
|
289 |
|
290 | detect_keypad();
|
291 |
|
292 | switch(page){
|
293 | case 0:
|
294 | if (old_idx != idx){
|
295 | if (idx == 1){
|
296 | page = 1;
|
297 | draw_UI();
|
298 | }else if (idx == 2){
|
299 | page = 2;
|
300 | draw_UI();
|
301 | }
|
302 | }
|
303 | break;
|
304 | case 1:
|
305 | manual_auto = 1;
|
306 | if (old_idx != idx){
|
307 | if (idx == 1){
|
308 | page = 11;
|
309 | draw_UI();
|
310 | }else if (idx == 2){
|
311 | page = 12;
|
312 | draw_UI();
|
313 | }else if (idx == 11){
|
314 | page = 0;
|
315 | draw_UI();
|
316 | manual_auto = 0;
|
317 | }
|
318 | }
|
319 | break;
|
320 | case 11:
|
321 | if (old_idx != idx){
|
322 | if (stop == 1 && idx == 0){
|
323 | stop = 0;
|
324 | }
|
325 | else if (idx <= 9 && 0 <= idx){
|
326 | temp_step = temp_step * 10 + idx;
|
327 | if (temp_step > 200){
|
328 | temp_step = 200;
|
329 | }
|
330 | sprintf(temp, "%s%.2f", "Degree Selection: ", temp_step*1.8);
|
331 | draw_UI();
|
332 | }else if (idx == 10){
|
333 | stepsPerRevolution = temp_step;
|
334 | rotate_flag = 1;
|
335 | temp_step = 0;
|
336 | stop = 0;
|
337 | }else if (idx == 11){
|
338 | page = 1;
|
339 | temp_step = 0;
|
340 | rotate_flag = 0;
|
341 | stop = 1;
|
342 | sprintf(temp, "%s%.2f", "Degree Selection: ", temp_step*1.8);
|
343 | draw_UI();
|
344 | }
|
345 | }
|
346 | break;
|
347 | case 12:
|
348 | if (idx == 2){
|
349 | lift = 1;
|
350 | }else if (idx == 5){
|
351 | lift = 2;
|
352 | }else if (idx == 3 && old_idx != idx){
|
353 | lift = 3;
|
354 | }else if (idx == 6 && old_idx != idx){
|
355 | lift = 4;
|
356 | }else if (idx == 11 && old_idx != idx){
|
357 | page = 1;
|
358 | lift = 0;
|
359 | draw_UI();
|
360 | }
|
361 | break;
|
362 | case 2:
|
363 | switch (auto_index){
|
364 | case 0:
|
365 | if (old_idx != idx){
|
366 | if (idx <= 9 && 0 <= idx){
|
367 | temp_step = temp_step * 10 + idx;
|
368 | if (temp_step > 200){
|
369 | temp_step = 200;
|
370 | }
|
371 | sprintf(temp, "%s%.2f", "Degree Selection: ", temp_step*1.8);
|
372 | draw_UI();
|
373 | }else if (idx == 10){
|
374 | stepsPerRevolution = temp_step;
|
375 | temp_step = 0;
|
376 | temp_step2 = 0;
|
377 | temp_step3 = 0;
|
378 | auto_index = 1;
|
379 | draw_UI();
|
380 | }else if (idx == 11){
|
381 | page = 0;
|
382 | temp_step = 0;
|
383 | temp_step2 = 0;
|
384 | temp_step3 = 0;
|
385 | draw_UI();
|
386 | }
|
387 | }
|
388 | break;
|
389 | case 1:
|
390 | if (old_idx != idx){
|
391 | if (idx <= 9 && 0 <= idx){
|
392 | temp_step2 = temp_step2 * 10 + idx;
|
393 | sprintf(temp1, "%s%d%s", "Degree Interval: ", temp_step2, "(s)");
|
394 | draw_UI();
|
395 | }else if (idx == 10){
|
396 | interval = temp_step2;
|
397 | auto_index = 2;
|
398 | temp_step = 0;
|
399 | temp_step2 = 0;
|
400 | temp_step3 = 0;
|
401 | draw_UI();
|
402 | }else if (idx == 11){
|
403 | page = 0;
|
404 | temp_step = 0;
|
405 | temp_step2 = 0;
|
406 | temp_step3 = 0;
|
407 | draw_UI();
|
408 | }
|
409 | }
|
410 | break;
|
411 | case 2:
|
412 | if (idx == 2){
|
413 | gpio_put(dirPin_lift, 0);
|
414 | sleep_ms(2);
|
415 | gpio_put(stepPin_lift, 1);
|
416 | sleep_ms(2);
|
417 | gpio_put(stepPin_lift, 0);
|
418 | sleep_ms(2);
|
419 | }else if (idx == 5){
|
420 | gpio_put(dirPin_lift, 1);
|
421 | sleep_ms(2);
|
422 | gpio_put(stepPin_lift, 1);
|
423 | sleep_ms(2);
|
424 | gpio_put(stepPin_lift, 0);
|
425 | sleep_ms(2);
|
426 | }else if (idx == 10 && old_idx != idx){
|
427 | auto_index = 3;
|
428 | temp_step = 0;
|
429 | temp_step2 = 0;
|
430 | temp_step3 = 0;
|
431 | draw_UI();
|
432 | }else if (idx == 11 && old_idx != idx){
|
433 | page = 0;
|
434 | temp_step = 0;
|
435 | temp_step2 = 0;
|
436 | temp_step3 = 0;
|
437 | draw_UI();
|
438 | }
|
439 | break;
|
440 | case 3:
|
441 | if (old_idx != idx){
|
442 | if (idx <= 9 && 0 <= idx){
|
443 | temp_step3 = temp_step3 * 10 + idx;
|
444 | sprintf(temp2, "%s%d%s", "Lift Interval: ", temp_step3, "(cm)");
|
445 | draw_UI();
|
446 | }else if (idx == 10){
|
447 | interval2 = temp_step3;
|
448 | temp_step = 0;
|
449 | temp_step2 = 0;
|
450 | temp_step3 = 0;
|
451 | manual_auto = 2;
|
452 | draw_UI();
|
453 | }else if (idx == 11){
|
454 | page = 0;
|
455 | temp_step = 0;
|
456 | temp_step2 = 0;
|
457 | temp_step3 = 0;
|
458 | draw_UI();
|
459 | }
|
460 | }
|
461 | break;
|
462 | }
|
463 |
|
464 | if (idx == 11 && old_idx != idx){
|
465 | page = 0;
|
466 | manual_auto = 0;
|
467 | }
|
468 | break;
|
469 | default:
|
470 | break;
|
471 | }
|
472 |
|
473 |
|
474 |
|
475 | old_idx = idx;
|
476 |
|
477 | spare_time = FRAME_RATE - (time_us_32() - begin_time) ;
|
478 |
|
479 | PT_YIELD_usec(spare_time) ;
|
480 | }
|
481 |
|
482 |
|
483 |
|
484 | PT_END(pt);
|
485 | }
|
486 |
|
487 | int count = 0;;
|
488 | static PT_THREAD (protothread_serial(struct pt *pt))
|
489 | {
|
490 |
|
491 | PT_BEGIN(pt) ;
|
492 | int s;
|
493 |
|
494 | if (manual_auto==1){
|
495 |
|
496 | if (rotate_flag == 1 && stop == 0){
|
497 |
|
498 | gpio_put(dirPin_rotation, 1);
|
499 |
|
500 | degree += stepsPerRevolution * 1.8;
|
501 | draw_rotation_platform();
|
502 | draw_rotation_text();
|
503 | for(int x = 0; x < stepsPerRevolution; x++){
|
504 | gpio_put(stepPin_rotation, 1);
|
505 | sleep_ms(10);
|
506 | gpio_put(stepPin_rotation, 0);
|
507 | sleep_ms(10);
|
508 | }
|
509 | if (degree >= 360.0){
|
510 | rotate_flag = 0;
|
511 | degree = 0.0;
|
512 | sprintf(temp, "%s%.2f", "Current Degree is ", temp_step*1.8);
|
513 | draw_UI();
|
514 | draw_rotation_platform();
|
515 | draw_rotation_text();
|
516 | }
|
517 | stop = 1;
|
518 | }
|
519 |
|
520 | switch (lift){
|
521 | case 1:
|
522 | gpio_put(dirPin_lift, 0);
|
523 | sleep_ms(2);
|
524 | gpio_put(stepPin_lift, 1);
|
525 | sleep_ms(2);
|
526 | gpio_put(stepPin_lift, 0);
|
527 | sleep_ms(2);
|
528 | lift = 0;
|
529 | break;
|
530 | case 2:
|
531 | gpio_put(dirPin_lift, 1);
|
532 | sleep_ms(2);
|
533 | gpio_put(stepPin_lift, 1);
|
534 | sleep_ms(2);
|
535 | gpio_put(stepPin_lift, 0);
|
536 | sleep_ms(2);
|
537 | lift = 0;
|
538 | break;
|
539 | case 3:
|
540 | gpio_put(dirPin_lift, 0);
|
541 | for(int x = 0; x < 545; x++){
|
542 | gpio_put(stepPin_lift, 1);
|
543 | sleep_ms(6);
|
544 | gpio_put(stepPin_lift, 0);
|
545 | sleep_ms(6);
|
546 | }
|
547 | lift = 0;
|
548 | break;
|
549 | case 4:
|
550 | gpio_put(dirPin_lift, 1);
|
551 | for(int x = 0; x < 545; x++){
|
552 | gpio_put(stepPin_lift, 1);
|
553 | sleep_ms(6);
|
554 | gpio_put(stepPin_lift, 0);
|
555 | sleep_ms(6);
|
556 | }
|
557 | lift = 0;
|
558 | break;
|
559 | default:
|
560 | break;
|
561 | }
|
562 | }else if (manual_auto == 2){
|
563 |
|
564 | int step = 200 / stepsPerRevolution;
|
565 | for(int i = 0; i < step; i++){
|
566 |
|
567 | gpio_put(dirPin_rotation, 1);
|
568 |
|
569 | printf("%f",degree);
|
570 | degree += stepsPerRevolution * 1.8;
|
571 | draw_rotation_platform();
|
572 | draw_rotation_text();
|
573 | for(int x = 0; x < stepsPerRevolution; x++){
|
574 | gpio_put(stepPin_rotation, 1);
|
575 | sleep_ms(10);
|
576 | gpio_put(stepPin_rotation, 0);
|
577 | sleep_ms(10);
|
578 | }
|
579 | sleep_ms(interval*1000);
|
580 | }
|
581 | degree = 0.0;
|
582 | for (int i=0; i<interval2;i++){
|
583 | gpio_put(dirPin_lift, 0);
|
584 | for(int x = 0; x < 545; x++){
|
585 | gpio_put(stepPin_lift, 1);
|
586 | sleep_ms(6);
|
587 | gpio_put(stepPin_lift, 0);
|
588 | sleep_ms(6);
|
589 | }
|
590 | sleep_ms(interval*1000);
|
591 |
|
592 | int step = 200 / stepsPerRevolution;
|
593 | for(int i = 0; i < step; i++){
|
594 |
|
595 | gpio_put(dirPin_rotation, 1);
|
596 |
|
597 | degree += stepsPerRevolution * 1.8;
|
598 | draw_rotation_platform();
|
599 | draw_rotation_text();
|
600 | for(int x = 0; x < stepsPerRevolution; x++){
|
601 | gpio_put(stepPin_rotation, 1);
|
602 | sleep_ms(10);
|
603 | gpio_put(stepPin_rotation, 0);
|
604 | sleep_ms(10);
|
605 | }
|
606 | sleep_ms(interval*1000);
|
607 | }
|
608 | degree = 0.0;
|
609 | }
|
610 | }
|
611 |
|
612 |
|
613 | PT_END(pt);
|
614 | }
|
615 |
|
616 |
|
617 | void core1_entry() {
|
618 | pt_add_thread(protothread_vga) ;
|
619 | pt_schedule_start ;
|
620 | }
|
621 |
|
622 | int main() {
|
623 |
|
624 | stdio_init_all();
|
625 |
|
626 | gpio_init(stepPin_rotation);
|
627 | gpio_init(dirPin_rotation);
|
628 | gpio_init(stepPin_lift);
|
629 | gpio_init(dirPin_lift);
|
630 | gpio_set_dir(stepPin_lift, GPIO_OUT);
|
631 | gpio_set_dir(dirPin_lift, GPIO_OUT);
|
632 | gpio_set_dir(stepPin_rotation, GPIO_OUT);
|
633 | gpio_set_dir(dirPin_rotation, GPIO_OUT);
|
634 |
|
635 |
|
636 |
|
637 | gpio_init_mask((0x7F << BASE_KEYPAD_PIN)) ;
|
638 |
|
639 | gpio_set_dir_out_masked((0xF << BASE_KEYPAD_PIN)) ;
|
640 |
|
641 | gpio_put_masked((0xF << BASE_KEYPAD_PIN), (0x0 << BASE_KEYPAD_PIN)) ;
|
642 |
|
643 | gpio_pull_down((BASE_KEYPAD_PIN + 4)) ;
|
644 | gpio_pull_down((BASE_KEYPAD_PIN + 5)) ;
|
645 | gpio_pull_down((BASE_KEYPAD_PIN + 6)) ;
|
646 |
|
647 |
|
648 | initVGA() ;
|
649 |
|
650 |
|
651 | multicore_reset_core1();
|
652 | multicore_launch_core1(core1_entry);
|
653 |
|
654 |
|
655 | pt_add_thread(protothread_serial) ;
|
656 | pt_schedule_start ;
|
657 | }
|
658 | |