2 コミット

作成者 SHA1 メッセージ 日付
  Thomas Buck a7224e83cb some hardware design modifications, added endstop mounts. 2年前
  Thomas Buck 6d5dc579da updated code for use with first prototype of xy table 2年前
18個のファイルの変更749行の追加108行の削除
  1. 37
    1
      hardware/config.scad
  2. 11
    3
      hardware/fuellfix.scad
  3. 207
    20
      hardware/table.scad
  4. 3
    0
      include/common.h
  5. 15
    7
      include/config.h
  6. 2
    2
      include/config_pins.h
  7. 1
    0
      include/encoder.h
  8. 8
    2
      include/statemachine.h
  9. 2
    0
      include/states.h
  10. 6
    0
      include/steppers.h
  11. 2
    0
      platformio.ini
  12. 7
    0
      src/debounce.cpp
  13. 4
    0
      src/encoder.cpp
  14. 8
    0
      src/lcd.cpp
  15. 52
    31
      src/main.cpp
  16. 31
    7
      src/statemachine.cpp
  17. 125
    13
      src/states.cpp
  18. 228
    22
      src/steppers.cpp

+ 37
- 1
hardware/config.scad ファイルの表示

@@ -157,6 +157,21 @@ y_carriage_post_hole_off = 2;
157 157
 y_carriage_post_center = 1;
158 158
 y_carriage_post_screw_hole = y_carriage_post_screw + nut_gap;
159 159
 y_carriage_post_len = y_carriage_rail_dist - rail_wheel_height / 2 + 10;
160
+echo("y_carriage_post_len", y_carriage_post_len);
161
+
162
+eccentric_height_main = 8.5;
163
+eccentric_height_inset = 2.4;
164
+eccentric_dia_inset = 7.3;
165
+eccentric_dia_main = 11.5;
166
+eccentric_hole_off = 0.75;
167
+eccentric_screw_hole = y_carriage_post_screw_hole + 2 * eccentric_hole_off;
168
+eccentric_height_add = y_carriage_post_len - eccentric_height_main;
169
+eccentric_inset_wall = 15.0;
170
+eccentric_inset_hole = eccentric_height_inset + 0.6;
171
+eccentric_screw_hole_h = 6.5;
172
+eccentric_screw_hole_dia = 15.0 + 2 * eccentric_hole_off;
173
+
174
+use_custom_eccentric = true;
160 175
 
161 176
 y_carriage_wheel_off_x = 20.4;
162 177
 y_carriage_wheel_off_y = 28;
@@ -211,7 +226,7 @@ x_axis_rail_len = x_axis_travel_len + y_carriage_y + motor_mount_length + belt_t
211 226
 point_that_reaches_everywhere_x = -7.5;
212 227
 point_that_reaches_everywhere_y = -17.5;
213 228
 
214
-use_anim = true;
229
+use_anim = false;
215 230
 x_axis_position = 1.0;
216 231
 y_axis_position = 0.5;
217 232
 
@@ -236,3 +251,24 @@ right_support_len = 200;
236 251
 right_support_off = 50;
237 252
 
238 253
 echo("distance between bottom support rails", x_axis_rail_len - left_support_off - right_support_off - 40, -left_support_off, -right_support_off);
254
+
255
+endstop_pcb_width = 16.0;
256
+endstop_pcb_height = 40.0;
257
+endstop_pcb_depth = 1.6;
258
+endstop_pcb_hole = 3.2;
259
+endstop_pcb_hole_dist_x = 3.2;
260
+endstop_pcb_hole_dist_y = 3.2;
261
+endstop_pcb_hole_dist = 19.0;
262
+endstop_pcb_switchpoint = 4.5;
263
+endstop_mount_width = 12;
264
+endstop_mount_depth = 5;
265
+endstop_mount_slot_width = 6;
266
+endstop_mount_slot_depth = 4;
267
+endstop_mount_slot_length = 8;
268
+endstop_mount_add_height = 15;
269
+endstop_mount_nut_hole = 6.5;
270
+endstop_pcb_mount_off_h = y_carriage_rail_dist + endstop_pcb_switchpoint + 2; // TODO is now -3
271
+endstop_pcb_mount_off_d = 18; // TODO was 8
272
+endstop_pcb_mount_off_w = endstop_mount_slot_length;
273
+
274
+use_endstop_mount_v2 = false;

+ 11
- 3
hardware/fuellfix.scad ファイルの表示

@@ -3,7 +3,7 @@ use <table.scad>;
3 3
 use <gearbox.scad>;
4 4
 use <common.scad>;
5 5
 
6
-draw_assembly = false;
6
+draw_assembly = true;
7 7
 
8 8
 module print() {
9 9
     for (i = [1 : 4])
@@ -43,6 +43,11 @@ module print() {
43 43
     translate([-real_belt_pulley_dia - i, belt_tensioner_moving_len + 20, 0])
44 44
     rotate([0, -90, 0])
45 45
     motor_mount(2);
46
+    
47
+    for (i = [0, -100])
48
+    translate([-real_belt_pulley_dia - 140, belt_tensioner_moving_len + i, endstop_mount_depth])
49
+    rotate([-90, 0, 0])
50
+    endstop_mount();
46 51
 }
47 52
 
48 53
 top_rail_len = x_axis_rail_len + plate_x - 70;
@@ -70,8 +75,11 @@ if (draw_assembly) {
70 75
     fuellfix_assembly();
71 76
 } else {
72 77
     //belt_pulley(teethcount, real_belt_pulley_dia, 0);
73
-    x_carriage_holder();
74
-    //print();
78
+    //x_carriage_holder();
79
+    //y_carriage(0);
80
+    //endstop_mount();
81
+    
82
+    print();
75 83
 }
76 84
     
77 85
 echo(); echo(); echo();

+ 207
- 20
hardware/table.scad ファイルの表示

@@ -254,6 +254,121 @@ module plate() {
254 254
  ************** Y-Axis **************
255 255
  ************************************/
256 256
 
257
+module endstop_pcb() {
258
+    difference() {
259
+        cube([endstop_pcb_width, endstop_pcb_depth, endstop_pcb_height]);
260
+        
261
+        for (i = [0, 1])
262
+        translate([endstop_pcb_hole_dist_x, -1, endstop_pcb_height - endstop_pcb_hole_dist_y - i * endstop_pcb_hole_dist])
263
+        rotate([-90, 0, 0])
264
+        cylinder(d = endstop_pcb_hole, h = endstop_pcb_depth + 2);
265
+    }
266
+    
267
+    translate([0, 0, endstop_pcb_height - endstop_pcb_switchpoint])
268
+    rotate([0, -90, 0])
269
+    cylinder(d = endstop_pcb_hole, h = endstop_pcb_switchpoint);
270
+}
271
+
272
+module endstop_mount_v1() {
273
+    %color("yellow")
274
+    translate([-endstop_pcb_mount_off_w, -endstop_pcb_depth - endstop_pcb_mount_off_d, endstop_pcb_mount_off_h])
275
+    endstop_pcb();
276
+    
277
+    color("blue")
278
+    difference() {
279
+        cube([endstop_mount_width, endstop_mount_depth, 40]);
280
+        
281
+        for (i = [0, 1])
282
+        translate([endstop_mount_width / 2, -1, 10 + 20 * i])
283
+        rotate([-90, 0, 0])
284
+        cylinder(d = motor_mount_hole_size, h = endstop_mount_depth + 2);
285
+    }
286
+    
287
+    color("blue")
288
+    difference() {
289
+        union() {
290
+            hull() {
291
+                translate([-endstop_mount_slot_length, 0, 40 - endstop_mount_add_height])
292
+                cube([endstop_mount_slot_length, endstop_mount_depth, endstop_mount_add_height]);
293
+                
294
+                translate([0, 0, endstop_pcb_height - endstop_pcb_hole_dist_y - endstop_pcb_hole_dist])
295
+                translate([-endstop_pcb_mount_off_w, -endstop_pcb_mount_off_d, endstop_pcb_mount_off_h - endstop_mount_slot_width / 2])
296
+                cube([endstop_mount_slot_length, endstop_mount_slot_depth, endstop_mount_slot_width]);
297
+                
298
+                for (i = [0, 1])
299
+                translate([0, 0, endstop_pcb_height - endstop_pcb_hole_dist_y - i * endstop_pcb_hole_dist])
300
+                translate([-endstop_pcb_mount_off_w, -endstop_pcb_mount_off_d, endstop_pcb_mount_off_h - endstop_mount_slot_width / 2])
301
+                cube([endstop_mount_slot_length, endstop_mount_slot_depth, endstop_mount_slot_width]);
302
+            }
303
+        }
304
+        
305
+        translate([-endstop_pcb_mount_off_w, -endstop_pcb_depth - endstop_pcb_mount_off_d, endstop_pcb_mount_off_h])
306
+        for (i = [0, 1])
307
+        translate([endstop_pcb_hole_dist_x, -1, endstop_pcb_height - endstop_pcb_hole_dist_y - i * endstop_pcb_hole_dist])
308
+        rotate([-90, 0, 0]) {
309
+            cylinder(d = endstop_pcb_hole, h = endstop_pcb_depth + 20);
310
+            
311
+            translate([0, 0, 1 + endstop_pcb_depth + endstop_mount_slot_depth])
312
+            cylinder(d = endstop_mount_nut_hole, h = 20, $fn = 6);
313
+        }
314
+    }
315
+}
316
+
317
+module endstop_mount_v2() {
318
+    %color("yellow")
319
+    translate([-endstop_pcb_mount_off_w, -endstop_pcb_depth - endstop_pcb_mount_off_d, endstop_pcb_mount_off_h])
320
+    endstop_pcb();
321
+    
322
+    color("blue")
323
+    difference() {
324
+        cube([endstop_mount_width, endstop_mount_depth, 40]);
325
+        
326
+        for (i = [0, 1])
327
+        translate([endstop_mount_width / 2, -1, 10 + 20 * i])
328
+        rotate([-90, 0, 0])
329
+        cylinder(d = motor_mount_hole_size, h = endstop_mount_depth + 2);
330
+    }
331
+    
332
+    color("blue")
333
+    difference() {
334
+        union() {
335
+            hull() {
336
+                translate([-endstop_mount_slot_length, 0, 40 - endstop_mount_add_height])
337
+                cube([endstop_mount_slot_length, endstop_mount_depth, endstop_mount_add_height]);
338
+                
339
+                translate([0, 0, endstop_pcb_height - endstop_pcb_hole_dist_y - endstop_pcb_hole_dist])
340
+                translate([-endstop_pcb_mount_off_w, -endstop_pcb_mount_off_d, endstop_pcb_mount_off_h - endstop_mount_slot_width / 2])
341
+                cube([endstop_mount_slot_length, endstop_mount_slot_depth, endstop_mount_slot_width]);
342
+            }
343
+            
344
+            hull() {
345
+                for (i = [0, 1])
346
+                translate([0, 0, endstop_pcb_height - endstop_pcb_hole_dist_y - i * endstop_pcb_hole_dist])
347
+                translate([-endstop_pcb_mount_off_w, -endstop_pcb_mount_off_d, endstop_pcb_mount_off_h - endstop_mount_slot_width / 2])
348
+                cube([endstop_mount_slot_length, endstop_mount_slot_depth, endstop_mount_slot_width]);
349
+            }
350
+        }
351
+        
352
+        translate([-endstop_pcb_mount_off_w, -endstop_pcb_depth - endstop_pcb_mount_off_d, endstop_pcb_mount_off_h])
353
+        for (i = [0, 1])
354
+        translate([endstop_pcb_hole_dist_x, -1, endstop_pcb_height - endstop_pcb_hole_dist_y - i * endstop_pcb_hole_dist])
355
+        rotate([-90, 0, 0]) {
356
+            cylinder(d = endstop_pcb_hole, h = endstop_pcb_depth + 20);
357
+            
358
+            translate([0, 0, 1 + endstop_pcb_depth + endstop_mount_slot_depth])
359
+            cylinder(d = endstop_mount_nut_hole, h = 20, $fn = 6);
360
+        }
361
+    }
362
+}
363
+
364
+module endstop_mount() {
365
+    if (use_endstop_mount_v2) {
366
+        endstop_mount_v2();
367
+    } else {
368
+        endstop_mount_v1();
369
+    }
370
+}
371
+
257 372
 module belt_mount(h) {
258 373
     difference() {
259 374
         hull() {
@@ -273,6 +388,15 @@ module belt_mount(h) {
273 388
     }
274 389
 }
275 390
 
391
+module eccentric() {
392
+    translate([0, 0, eccentric_height_add]) {
393
+        cylinder(d = eccentric_dia_main, h = eccentric_height_main);
394
+        
395
+        translate([0, 0, -eccentric_height_inset])
396
+        cylinder(d = eccentric_dia_inset, h = eccentric_height_inset);
397
+    }
398
+}
399
+
276 400
 module y_carriage_post() {
277 401
     rotate([0, 0, 90])
278 402
     difference() {
@@ -290,12 +414,21 @@ module y_carriage_posts() {
290 414
     for (i = [-1, 1])
291 415
     for (j = [-1, 1])
292 416
     translate([i * y_carriage_wheel_x_dist / 2, j * y_carriage_wheel_y_dist / 2, 0]) {
293
-        color("blue")
294
-        y_carriage_post();
417
+        if (use_custom_eccentric) {
418
+            color("yellow")
419
+            eccentric();
295 420
         
296
-        %color("yellow")
297
-        translate([0, y_carriage_post_hole_off, y_carriage_pulley_off])
298
-        rail_wheel();
421
+            %color("yellow")
422
+            translate([0, eccentric_hole_off, y_carriage_pulley_off])
423
+            rail_wheel();
424
+        } else {
425
+            color("blue")
426
+            y_carriage_post();
427
+        
428
+            %color("yellow")
429
+            translate([0, y_carriage_post_hole_off, y_carriage_pulley_off])
430
+            rail_wheel();
431
+        }
299 432
     }
300 433
 }
301 434
 
@@ -307,6 +440,12 @@ module y_carriage(axis = 0) {
307 440
     if (axis == 1) {
308 441
         echo("t-nut", "x-carriage", "2");
309 442
     }
443
+    
444
+    if (use_custom_eccentric) {
445
+        echo("eccentric", "carriage", "4");
446
+        echo("screw", "carriage", "M5x30", "4");
447
+        echo("nut", "carriage", "M5", "4");
448
+    }
310 449
 
311 450
     color("green")
312 451
     difference() {
@@ -318,6 +457,14 @@ module y_carriage(axis = 0) {
318 457
             translate([0, i * (y_carriage_y + belt_mount_depth) / 2, 0])
319 458
             scale([1, -i, 1])
320 459
             belt_mount(y_carriage_h);
460
+            
461
+            // additional "meat" for eccentric inset
462
+            translate([y_carriage_x / 2, y_carriage_y / 2, y_carriage_h])
463
+            for (i = [-1, 1])
464
+            for (j = [-1, 1])
465
+            translate([i * y_carriage_wheel_x_dist / 2, j * y_carriage_wheel_y_dist / 2, 0])
466
+            if (use_custom_eccentric)
467
+            cylinder(d = eccentric_inset_wall, h = eccentric_height_add);
321 468
         }
322 469
         
323 470
         translate([y_carriage_x / 2, y_carriage_y / 2, 0])
@@ -335,10 +482,19 @@ module y_carriage(axis = 0) {
335 482
             cylinder(d = y_carriage_post_screw_hole, h = y_carriage_h + 2);
336 483
         }
337 484
         
485
+        // holes for wheel posts
338 486
         translate([y_carriage_x / 2, y_carriage_y / 2, 0])
339 487
         for (i = [-1, 1])
340 488
         for (j = [-1, 1])
341
-        translate([i * y_carriage_wheel_x_dist / 2, j * y_carriage_wheel_y_dist / 2, -1]) {
489
+        translate([i * y_carriage_wheel_x_dist / 2, j * y_carriage_wheel_y_dist / 2, -1])
490
+        if (use_custom_eccentric) {
491
+            cylinder(d = eccentric_screw_hole, h = y_carriage_h + 2);
492
+            
493
+            translate([0, 0, y_carriage_h + eccentric_height_add + 1 - eccentric_inset_hole])
494
+            cylinder(d = eccentric_dia_inset, h = eccentric_inset_hole + 1);
495
+            
496
+            cylinder(d = eccentric_screw_hole_dia, h = eccentric_screw_hole_h + 1);
497
+        } else {
342 498
             cylinder(d = y_carriage_post_screw_hole, h = y_carriage_h + 2);
343 499
         }
344 500
     }
@@ -360,6 +516,10 @@ module y_axis() {
360 516
     rotate([180, 0, 0])
361 517
     motor_mount(2);
362 518
     
519
+    translate([10 + endstop_mount_depth, y_axis_rail_len - endstop_mount_width, -20])
520
+    rotate([0, 0, 90])
521
+    endstop_mount();
522
+    
363 523
     belt_tensioner(2, y_axis_rail_len, 0);
364 524
 }
365 525
 
@@ -396,6 +556,7 @@ module x_carriage() {
396 556
     rotate([0, 180, -90])
397 557
     y_carriage(1);
398 558
     
559
+    /*
399 560
     color("purple")
400 561
     for (i = [-1, 1])
401 562
     translate([y_carriage_y / 2, 0, 0])
@@ -403,6 +564,7 @@ module x_carriage() {
403 564
     translate([y_carriage_y / 2 - x_carriage_holder_l, 0, 0])
404 565
     translate([0, -x_carriage_holder_w / 2, 20 + y_carriage_h + y_carriage_rail_dist])
405 566
     x_carriage_holder();
567
+    */
406 568
 }
407 569
 
408 570
 module x_axis() {
@@ -417,6 +579,9 @@ module x_axis() {
417 579
     rotate([0, 180, 90])
418 580
     motor_mount(2);
419 581
     
582
+    translate([x_axis_rail_len - endstop_mount_width, -10 - endstop_mount_depth, -20])
583
+    endstop_mount();
584
+    
420 585
     rotate([0, 0, -90])
421 586
     belt_tensioner(2, x_axis_rail_len, 0);
422 587
 }
@@ -441,21 +606,43 @@ module assembly_x_axis() {
441 606
     assembly_y_axis_plate();
442 607
 }
443 608
 
609
+bottom_support_len = 500;
610
+bottom_support_off = 80;
611
+
612
+use_double_supports = false;
613
+
614
+module rail_foot() {
615
+    
616
+}
617
+
444 618
 module assembly() {
445 619
     translate([-x_axis_rail_len / 2, 0, 20]) {
446 620
         assembly_x_axis();
447 621
         
448
-        color("grey")
449
-        for (i = [1, -1])
450
-        scale([1, i, 1])
451
-        translate([left_support_off, -left_support_len - 10, -20])
452
-        rail_2020_y(left_support_len, "left support");
453
-        
454
-        color("grey")
455
-        for (i = [1, -1])
456
-        scale([1, i, 1])
457
-        translate([x_axis_rail_len - 20 - right_support_off, -right_support_len - 10, -20])
458
-        rail_2020_y(right_support_len, "right support");
622
+        if (use_double_supports) {
623
+            color("grey")
624
+            for (i = [1, -1])
625
+            scale([1, i, 1])
626
+            translate([left_support_off, -left_support_len - 10, -20])
627
+            rail_2020_y(left_support_len, "left support");
628
+            
629
+            color("grey")
630
+            for (i = [1, -1])
631
+            scale([1, i, 1])
632
+            translate([x_axis_rail_len - 20 - right_support_off, -right_support_len - 10, -20])
633
+            rail_2020_y(right_support_len, "right support");
634
+            
635
+            // TODO feet
636
+        } else {
637
+            color("grey")
638
+            translate([x_axis_rail_len / 2, 0, -40])
639
+            for (i = [1, -1])
640
+            scale([i, 1, 1])
641
+            translate([x_axis_rail_len / 2 - bottom_support_off, -bottom_support_len / 2, 0])
642
+            rail_2020_y(bottom_support_len, "bottom supports");
643
+            
644
+            // TODO feet
645
+        }
459 646
     }
460 647
 }
461 648
 
@@ -485,8 +672,8 @@ module xy_table() {
485 672
 //y_carriage_post();
486 673
 //x_carriage_holder();
487 674
 
488
-translate([0, -50, 0])
489
-y_carriage(0);
675
+//translate([0, -50, 0])
676
+//y_carriage(0);
490 677
 //y_carriage(1);
491 678
 //y_carriage(2);
492 679
 //x_carriage();
@@ -495,4 +682,4 @@ y_carriage(0);
495 682
 //x_axis();
496 683
 
497 684
 //assembly();
498
-//xy_table();
685
+xy_table();

+ 3
- 0
include/common.h ファイルの表示

@@ -1,6 +1,9 @@
1 1
 #ifndef _COMMON_H_
2 2
 #define _COMMON_H_
3 3
 
4
+#define CLEAR_STORE_INTERRUPTS() uint8_t prev_int_reg = SREG; cli()
5
+#define RESTORE_INTERRUPTS() SREG = prev_int_reg
6
+
4 7
 void async_beep(int time, int freq);
5 8
 void blocking_beep(int time, int freq, int repeat = 0);
6 9
 void common_run(unsigned long t);

+ 15
- 7
include/config.h ファイルの表示

@@ -72,12 +72,12 @@
72 72
 #define E_MAX_SPEED 50.0 // in percent/s
73 73
 
74 74
 // homing speeds
75
-#define XY_FAST_HOME_SPEED 2.5 // in mm/s
76
-#define XY_SLOW_HOME_SPEED 1.0 // in mm/s
77
-#define Z_FAST_HOME_SPEED 2.0 // in mm/s
75
+#define XY_FAST_HOME_SPEED 25.0 // in mm/s
76
+#define XY_SLOW_HOME_SPEED 5.0 // in mm/s
77
+#define Z_FAST_HOME_SPEED 5.0 // in mm/s
78 78
 #define Z_SLOW_HOME_SPEED 1.0 // in mm/s
79 79
 #define E_FAST_HOME_SPEED 10.0 // in percent/s
80
-#define E_SLOW_HOME_SPEED 5.0 // in percent/s
80
+#define E_SLOW_HOME_SPEED 2.0 // in percent/s
81 81
 
82 82
 // accelerations
83 83
 #define XY_MAX_ACCEL 100.0 // in mm/s^2
@@ -91,12 +91,20 @@
91 91
 #define E_AXIS_MOVEMENT_DIR 1.0
92 92
 
93 93
 // homing back-off
94
-#define XY_BACK_OFF_DISTANCE 10.0 // in mm
95
-#define Z_BACK_OFF_DISTANCE 5.0 // in mm
96
-#define E_BACK_OFF_DISTANCE 2.0 // in mm
94
+#define XY_BACK_OFF_DISTANCE 5.0 // in mm
95
+#define Z_BACK_OFF_DISTANCE 2.0 // in mm
96
+#define E_BACK_OFF_DISTANCE 1.0 // in mm
97 97
 
98 98
 #define XY_HOME_BACK_OFF_TIME (XY_BACK_OFF_DISTANCE / XY_FAST_HOME_SPEED * 1000)
99 99
 #define Z_HOME_BACK_OFF_TIME (Z_BACK_OFF_DISTANCE / Z_FAST_HOME_SPEED * 1000)
100 100
 #define E_HOME_BACK_OFF_TIME (E_BACK_OFF_DISTANCE / E_FAST_HOME_SPEED * 1000)
101 101
 
102
+// epsilon around expected endstop position where we dont abort on hits
103
+#define X_AXIS_EPSILON 20.0 // TODO
104
+#define Y_AXIS_EPSILON 20.0 // TODO
105
+#define Z_AXIS_EPSILON 1.0
106
+#define E_AXIS_EPSILON 1.0
107
+
108
+#define ENCODER_RPM_VALUE_FACTOR 10.0
109
+
102 110
 #endif // _CONFIG_H_

+ 2
- 2
include/config_pins.h ファイルの表示

@@ -41,12 +41,12 @@
41 41
 
42 42
 #define LED_PIN            13
43 43
 
44
-#define FAN_PIN            9
44
+#define FAN_PIN            8
45 45
 
46 46
 #define PS_ON_PIN          12	//ATX , awake=LOW, SLEEP=High
47 47
 
48 48
 #define HEATER_0_PIN	10  // Extruder Heater
49
-#define HEATER_1_PIN	8
49
+#define HEATER_1_PIN	9
50 50
 
51 51
 #define TEMP_0_PIN		13   // ANALOG NUMBERING
52 52
 #define TEMP_1_PIN		14   // ANALOG NUMBERING

+ 1
- 0
include/encoder.h ファイルの表示

@@ -5,6 +5,7 @@ void encoder_init(void);
5 5
 void encoder_run(void);
6 6
 
7 7
 int encoder_change(void);
8
+int encoder_rpm(void);
8 9
 int encoder_click(void);
9 10
 int kill_switch(void);
10 11
 

+ 8
- 2
include/statemachine.h ファイルの表示

@@ -12,11 +12,12 @@ template <typename T, size_t N>
12 12
 void array_insert_at_pos(Array<T, N> *arr, T value, size_t pos);
13 13
 
14 14
 struct StateMachineInput {
15
-    StateMachineInput(int c, int e, int k, int m)
16
-            : click(c), encoder(e), kill(k), motors_done(m) { };
15
+    StateMachineInput(int c, int e, int r, int k, int m)
16
+            : click(c), encoder(e), rpm(r), kill(k), motors_done(m) { };
17 17
 
18 18
     int click;
19 19
     int encoder;
20
+    int rpm;
20 21
     int kill;
21 22
     int motors_done;
22 23
 };
@@ -54,6 +55,8 @@ public:
54 55
     void onEnter(EnterFuncPtr func);
55 56
     void whenIn(InFuncPtr func);
56 57
 
58
+    void updateText(void);
59
+
57 60
     virtual void enterState(void);
58 61
     virtual void inState(StateMachineInput smi);
59 62
 
@@ -151,8 +154,10 @@ public:
151 154
     void setHeading(const char *_heading);
152 155
     void setText(const char *_text);
153 156
 
157
+    typedef void(*EnterFuncPtr)(void);
154 158
     typedef void(*UpdateFuncPtr)(size_t index, T value);
155 159
 
160
+    void onEnter(EnterFuncPtr func);
156 161
     void onLiveUpdate(UpdateFuncPtr func);
157 162
     void onUpdate(UpdateFuncPtr func);
158 163
 
@@ -168,6 +173,7 @@ private:
168 173
     const char *heading;
169 174
     size_t pos;
170 175
     bool editing;
176
+    EnterFuncPtr onEnterFunc;
171 177
     UpdateFuncPtr updateFunc, updateLiveFunc;
172 178
 };
173 179
 

+ 2
- 0
include/states.h ファイルの表示

@@ -9,4 +9,6 @@ void states_run(struct StateMachineInput smi);
9 9
 State *states_get(void);
10 10
 void states_go_to(State *state);
11 11
 
12
+extern StateText sm_error;
13
+
12 14
 #endif // _STATES_H_

+ 6
- 0
include/steppers.h ファイルの表示

@@ -5,8 +5,12 @@ void steppers_init(void);
5 5
 bool steppers_run(void);
6 6
 
7 7
 bool steppers_homed(void);
8
+char steppers_homing_axis(void);
8 9
 void steppers_start_homing(void);
9 10
 
11
+float steppers_current_pos(int axis);
12
+
13
+// target pos
10 14
 float steppers_pos_x(void);
11 15
 float steppers_pos_y(void);
12 16
 float steppers_pos_z(void);
@@ -29,4 +33,6 @@ void steppers_set_accel_y(float accel);
29 33
 void steppers_set_accel_z(float accel);
30 34
 void steppers_set_accel_e(float accel);
31 35
 
36
+bool steppers_home_switch(int axis);
37
+
32 38
 #endif // _STEPPERS_H_

+ 2
- 0
platformio.ini ファイルの表示

@@ -24,6 +24,7 @@ lib_deps =
24 24
     https://github.com/waspinator/AccelStepper
25 25
     https://github.com/mathertel/RotaryEncoder
26 26
     https://github.com/janelia-arduino/Array
27
+    https://github.com/PaulStoffregen/TimerOne
27 28
 
28 29
 [env:ramps_lcd12864]
29 30
 platform = atmelavr
@@ -38,3 +39,4 @@ lib_deps =
38 39
     https://github.com/waspinator/AccelStepper
39 40
     https://github.com/mathertel/RotaryEncoder
40 41
     https://github.com/janelia-arduino/Array
42
+    https://github.com/PaulStoffregen/TimerOne

+ 7
- 0
src/debounce.cpp ファイルの表示

@@ -19,6 +19,13 @@ int Debouncer::poll() {
19 19
             if (currentState == LOW) {
20 20
                 ret = 1;
21 21
             }
22
+
23
+            /*
24
+            Serial.print("Debounce: ");
25
+            Serial.print(pin);
26
+            Serial.print(" = ");
27
+            Serial.println(state);
28
+            */
22 29
         }
23 30
     }
24 31
 

+ 4
- 0
src/encoder.cpp ファイルの表示

@@ -63,6 +63,10 @@ int encoder_change(void) {
63 63
     return diff;
64 64
 }
65 65
 
66
+int encoder_rpm(void) {
67
+    return encoder.getRPM();
68
+}
69
+
66 70
 int encoder_click(void) {
67 71
     int r = click_state;
68 72
 

+ 8
- 0
src/lcd.cpp ファイルの表示

@@ -25,6 +25,8 @@ LiquidCrystal lcd(LCD_PINS_RS, LCD_PINS_ENABLE, LCD_PINS_D4, LCD_PINS_D5, LCD_PI
25 25
 
26 26
 #include <U8g2lib.h>
27 27
 
28
+//#define ENABLE_DYNAMIC_SCROLLING
29
+
28 30
 #define LCD_HEADING_LINES 1
29 31
 #define LCD_HEADING_WIDTH 15
30 32
 #define LCD_TEXT_LINES 5
@@ -111,6 +113,8 @@ void lcd_shorten_multiline(String s[], int n, int w, String *remainder) {
111 113
     last_scroll_time = millis();
112 114
 }
113 115
 
116
+#ifdef ENABLE_DYNAMIC_SCROLLING
117
+
114 118
 void lcd_scroll_multiline(String s[], int n, int w, String &pre, String &post, int &dir) {
115 119
     if (dir == 0) {
116 120
         // switch directions if done scrolling in current direction
@@ -180,6 +184,8 @@ void lcd_scrolling(void) {
180 184
     }
181 185
 }
182 186
 
187
+#endif // ENABLE_DYNAMIC_SCROLLING
188
+
183 189
 int lcd_text_lines(void) {
184 190
     return LCD_TEXT_LINES;
185 191
 }
@@ -221,10 +227,12 @@ void lcd_init(void) {
221 227
 }
222 228
 
223 229
 void lcd_loop(void) {
230
+#ifdef ENABLE_DYNAMIC_SCROLLING
224 231
     if ((millis() - last_scroll_time) >= SCROLL_DELAY) {
225 232
         last_scroll_time = millis();
226 233
         lcd_scrolling();
227 234
     }
235
+#endif // ENABLE_DYNAMIC_SCROLLING
228 236
 
229 237
 #ifdef USE_FULL_GRAPHIC_LCD
230 238
     if (redraw) {

+ 52
- 31
src/main.cpp ファイルの表示

@@ -1,4 +1,5 @@
1 1
 #include <Arduino.h>
2
+#include <TimerOne.h>
2 3
 
3 4
 #include "config.h"
4 5
 #include "config_pins.h"
@@ -9,32 +10,9 @@
9 10
 #include "steppers.h"
10 11
 #include "states.h"
11 12
 
12
-void setup() {
13
-    pinMode(LED_PIN, OUTPUT);
14
-    digitalWrite(LED_PIN, HIGH);
15
-
16
-    pinMode(BEEPER, OUTPUT);
17
-    blocking_beep(100, 1000);
18
-    
19
-    Serial.begin(115200);
20
-    Serial.println(F("Initializing Fuellfix v2"));
21
-    Serial.print(F("Version: "));
22
-    Serial.println(FIRMWARE_VERSION);
23
-
24
-    Serial.println(F("Init data"));
25
-    data_init();
26
-
27
-    Serial.println(F("Init encoder"));
28
-    encoder_init();
29
-
30
-    Serial.println(F("Init LCD"));
31
-    lcd_init();
32
-
33
-    Serial.println(F("Init stepper motors"));
34
-    steppers_init();
35
-
36
-    // ----------------------------------
13
+static volatile bool still_running = false;
37 14
 
15
+void print_data(void) {
38 16
     Serial.println(F("XY:"));
39 17
 
40 18
     Serial.print(F("\t X: "));
@@ -110,8 +88,42 @@ void setup() {
110 88
     Serial.println(F(" percent/s^2"));
111 89
 
112 90
     Serial.println();
91
+}
113 92
 
114
-    // ----------------------------------
93
+void fast_loop(void) {
94
+    still_running = steppers_run();
95
+    encoder_run();
96
+}
97
+
98
+void setup() {
99
+    pinMode(LED_PIN, OUTPUT);
100
+    digitalWrite(LED_PIN, HIGH);
101
+
102
+    pinMode(BEEPER, OUTPUT);
103
+    blocking_beep(100, 1000);
104
+
105
+    // turn on fan connected to D8 for electronics
106
+    pinMode(FAN_PIN, OUTPUT);
107
+    digitalWrite(FAN_PIN, HIGH);
108
+
109
+    Serial.begin(115200);
110
+    Serial.println(F("Initializing Fuellfix v2"));
111
+    Serial.print(F("Version: "));
112
+    Serial.println(FIRMWARE_VERSION);
113
+
114
+    Serial.println(F("Init data"));
115
+    data_init();
116
+
117
+    Serial.println(F("Init encoder"));
118
+    encoder_init();
119
+
120
+    Serial.println(F("Init LCD"));
121
+    lcd_init();
122
+
123
+    Serial.println(F("Init stepper motors"));
124
+    steppers_init();
125
+
126
+    print_data();
115 127
 
116 128
     Serial.println(F("ready, showing splash screen"));
117 129
     digitalWrite(LED_PIN, LOW);
@@ -125,19 +137,28 @@ void setup() {
125 137
 
126 138
     blocking_beep(100, 2000);
127 139
     Serial.println(F("starting main loop"));
140
+
141
+    Timer1.initialize(1000); // 1000us -> 1kHz
142
+    Timer1.attachInterrupt(fast_loop);
128 143
 }
129 144
 
130 145
 void loop() {
131
-    unsigned long t = millis();
132
-    common_run(t);
133
-    bool still_running = steppers_run();
134
-    encoder_run();
146
+    common_run(millis());
147
+
148
+    CLEAR_STORE_INTERRUPTS();
135 149
 
136 150
     int click = encoder_click();
151
+    int change = encoder_change();
152
+    int rpm = encoder_rpm();
137 153
     int kill = kill_switch();
154
+    bool motors_done = !still_running;
155
+
156
+    RESTORE_INTERRUPTS();
138 157
 
139
-    struct StateMachineInput smi(click, encoder_change(), kill, !still_running);
158
+    struct StateMachineInput smi(click, change, rpm, kill, motors_done);
140 159
     states_run(smi);
141 160
 
142 161
     lcd_loop();
162
+
163
+    delay(10);
143 164
 }

+ 31
- 7
src/statemachine.cpp ファイルの表示

@@ -45,11 +45,7 @@ void StateText::whenIn(InFuncPtr func) {
45 45
     whenInFunc = func;
46 46
 }
47 47
 
48
-void StateText::enterState(void) {
49
-    if (onEnterFunc != NULL) {
50
-        onEnterFunc();
51
-    }
52
-
48
+void StateText::updateText(void) {
53 49
     lcd_clear();
54 50
     if (heading != NULL) {
55 51
         lcd_set_heading(heading);
@@ -61,6 +57,14 @@ void StateText::enterState(void) {
61 57
     }
62 58
 }
63 59
 
60
+void StateText::enterState(void) {
61
+    if (onEnterFunc != NULL) {
62
+        onEnterFunc();
63
+    }
64
+
65
+    updateText();
66
+}
67
+
64 68
 void StateText::inState(struct StateMachineInput smi) {
65 69
     if (whenInFunc != NULL) {
66 70
         whenInFunc(smi);
@@ -325,7 +329,10 @@ void StateValue<T>::enterState(void) {
325 329
 template <typename T>
326 330
 void StateValue<T>::inState(StateMachineInput smi) {
327 331
     if (smi.encoder != 0) {
328
-        value -= smi.encoder;
332
+        float vf = smi.encoder;
333
+        vf *= 1.0 + ((float)smi.rpm / ENCODER_RPM_VALUE_FACTOR);
334
+        int v = vf;
335
+        value -= v;
329 336
         if (value < min) {
330 337
             value = min;
331 338
         }
@@ -353,6 +360,7 @@ template class StateValue<float>;
353 360
 template <typename T, size_t N>
354 361
 StateValues<T, N>::StateValues(State *_parent) : State(_parent) {
355 362
     heading = NULL;
363
+    onEnterFunc = NULL;
356 364
     updateFunc = NULL;
357 365
     updateLiveFunc = NULL;
358 366
     pos = 0;
@@ -376,6 +384,11 @@ void StateValues<T, N>::setHeading(const char *_heading) {
376 384
 }
377 385
 
378 386
 template <typename T, size_t N>
387
+void StateValues<T, N>::onEnter(EnterFuncPtr func) {
388
+    onEnterFunc = func;
389
+}
390
+
391
+template <typename T, size_t N>
379 392
 void StateValues<T, N>::onUpdate(UpdateFuncPtr func) {
380 393
     updateFunc = func;
381 394
 }
@@ -425,6 +438,9 @@ void StateValues<T, N>::display(void) {
425 438
 template <typename T, size_t N>
426 439
 void StateValues<T, N>::enterState(void) {
427 440
     pos = 0;
441
+    if (onEnterFunc != NULL) {
442
+        onEnterFunc();
443
+    }
428 444
     display();
429 445
 }
430 446
 
@@ -432,16 +448,23 @@ template <typename T, size_t N>
432 448
 void StateValues<T, N>::inState(StateMachineInput smi) {
433 449
     if (editing) {
434 450
         if (smi.encoder != 0) {
435
-            *(values[pos]) -= smi.encoder;
451
+            float vf = smi.encoder;
452
+            vf *= 1.0 + ((float)smi.rpm / ENCODER_RPM_VALUE_FACTOR);
453
+            int v = vf;
454
+            *(values[pos]) -= v;
455
+
436 456
             if (*(values[pos]) < mins[pos]) {
437 457
                 *(values[pos]) = mins[pos];
438 458
             }
459
+
439 460
             if (*(values[pos]) > maxs[pos]) {
440 461
                 *(values[pos]) = maxs[pos];
441 462
             }
463
+
442 464
             if (updateLiveFunc != NULL) {
443 465
                 updateLiveFunc(pos, *(values[pos]));
444 466
             }
467
+
445 468
             display();
446 469
         }
447 470
         if (smi.click) {
@@ -475,6 +498,7 @@ void StateValues<T, N>::inState(StateMachineInput smi) {
475 498
                         updateFunc(i, *(values[i]));
476 499
                     }
477 500
                 }
501
+
478 502
                 if (getChild() != NULL) {
479 503
                     states_go_to(getChild());
480 504
                 } else if (getParent() != NULL) {

+ 125
- 13
src/states.cpp ファイルの表示

@@ -9,6 +9,10 @@
9 9
 #include "statemachine.h"
10 10
 #include "states.h"
11 11
 
12
+//#define DISABLE_HOMING_STATE
13
+#define ENABLE_MOVEMENT_TEST_STATE
14
+#define ENABLE_INPUT_TEST_STATE
15
+
12 16
 // --------------------------------------
13 17
 
14 18
 StateText sm_ask_homing = StateText();
@@ -52,6 +56,18 @@ StateValue<float> sm_conf_accel_xy = StateValue<float>(&sm_config, data_options(
52 56
 StateValue<float> sm_conf_accel_z = StateValue<float>(&sm_config, data_options()->accel_z, 1.0, Z_MAX_ACCEL);
53 57
 StateValue<float> sm_conf_accel_e = StateValue<float>(&sm_config, data_options()->accel_e, 1.0, E_MAX_ACCEL);
54 58
 
59
+StateText sm_error = StateText(NULL);
60
+
61
+#ifdef ENABLE_MOVEMENT_TEST_STATE
62
+StateMenu sm_movement_test = StateMenu(&sm_menu);
63
+StateText sm_move_x_test = StateText(&sm_movement_test);
64
+StateText sm_move_y_test = StateText(&sm_movement_test);
65
+#endif // ENABLE_MOVEMENT_TEST_STATE
66
+
67
+#ifdef ENABLE_INPUT_TEST_STATE
68
+StateText sm_input_test = StateText(&sm_menu);
69
+#endif // ENABLE_INPUT_TEST_STATE
70
+
55 71
 // --------------------------------------
56 72
 
57 73
 State *current_state = NULL;
@@ -73,18 +89,33 @@ void states_init(void) {
73 89
     sm_do_homing.setHeading("Homing...");
74 90
 
75 91
     sm_do_homing.onEnter([]() {
76
-        //steppers_start_homing();
92
+#ifndef DISABLE_HOMING_STATE
93
+        steppers_start_homing();
94
+#endif // DISABLE_HOMING_STATE
77 95
     });
78 96
 
79 97
     sm_do_homing.whenIn([](StateMachineInput smi) {
80
-        //if (smi.motors_done) {
81
-        //    if (steppers_homed()) {
98
+#ifndef DISABLE_HOMING_STATE
99
+        if (smi.motors_done) {
100
+            if (steppers_homed()) {
101
+#endif // DISABLE_HOMING_STATE
102
+
82 103
                 async_beep(HOMING_BEEP_TIME, HOMING_BEEP_FREQ);
83 104
                 states_go_to(&sm_menu);
84
-        //    }
85
-        //}
86 105
 
87
-        // TODO update text with current axis
106
+#ifndef DISABLE_HOMING_STATE
107
+            }
108
+        }
109
+#endif // DISABLE_HOMING_STATE
110
+
111
+        static char last_axis = ' ';
112
+        char axis = steppers_homing_axis();
113
+        if ((axis != ' ') && (axis != last_axis)) {
114
+            last_axis = axis;
115
+            strbuf = String(F("Currently homing ")) + axis + String(F(" axis"));
116
+            sm_do_homing.setText(strbuf.c_str());
117
+            sm_do_homing.updateText();
118
+        }
88 119
     });
89 120
 
90 121
     // ----------------------------------
@@ -132,6 +163,7 @@ void states_init(void) {
132 163
 
133 164
     sm_auto.setTitle("Filling Menu");
134 165
 
166
+    // TODO
135 167
     sm_presets.setTitle("Use Preset");
136 168
     sm_presets.setPrefix("Preset ");
137 169
     sm_presets.dataCount([]() {
@@ -144,16 +176,27 @@ void states_init(void) {
144 176
 
145 177
     sm_wiz_move.setTitle("Initial Movement");
146 178
     sm_wiz_move.onEnter([]() {
147
-        //steppers_start_homing();
179
+        steppers_start_homing();
148 180
     });
149 181
     sm_wiz_move.whenIn([](StateMachineInput smi) {
150
-        //if (smi.motors_done) {
151
-        //    if (steppers_homed()) {
182
+#ifndef DISABLE_HOMING_STATE
183
+        if (smi.motors_done) {
184
+            if (steppers_homed()) {
185
+#endif // DISABLE_HOMING_STATE
152 186
                 states_go_to(&sm_wiz_count);
153
-        //    }
154
-        //}
155
-
156
-        // TODO update text with current axis
187
+#ifndef DISABLE_HOMING_STATE
188
+            }
189
+        }
190
+#endif // DISABLE_HOMING_STATE
191
+
192
+        static char last_axis = ' ';
193
+        char axis = steppers_homing_axis();
194
+        if ((axis != ' ') && (axis != last_axis)) {
195
+            last_axis = axis;
196
+            strbuf = String(F("Currently homing ")) + axis + String(F(" axis"));
197
+            sm_wiz_move.setText(strbuf.c_str());
198
+            sm_wiz_move.updateText();
199
+        }
157 200
     });
158 201
 
159 202
     sm_wiz_count.setTitle("Container Count");
@@ -163,6 +206,10 @@ void states_init(void) {
163 206
     sm_wiz_first_pos.setTitle("First Container Position");
164 207
     sm_wiz_first_pos.setData(0, "X: ", &wizard_first_x, X_AXIS_MIN, X_AXIS_MAX);
165 208
     sm_wiz_first_pos.setData(1, "Y: ", &wizard_first_y, Y_AXIS_MIN, Y_AXIS_MAX);
209
+    sm_wiz_first_pos.onEnter([]() {
210
+        wizard_first_x = steppers_current_pos(0);
211
+        wizard_first_y = steppers_current_pos(1);
212
+    });
166 213
     sm_wiz_first_pos.onLiveUpdate([](size_t i, float v) {
167 214
         if (i == 0) {
168 215
             steppers_move_x(v);
@@ -181,6 +228,10 @@ void states_init(void) {
181 228
     sm_wiz_last_pos.setTitle("Last Container Position");
182 229
     sm_wiz_last_pos.setData(0, "X: ", &wizard_last_x, X_AXIS_MIN, X_AXIS_MAX);
183 230
     sm_wiz_last_pos.setData(1, "Y: ", &wizard_last_y, Y_AXIS_MIN, Y_AXIS_MAX);
231
+    sm_wiz_last_pos.onEnter([]() {
232
+        wizard_last_x = steppers_current_pos(0);
233
+        wizard_last_y = steppers_current_pos(1);
234
+    });
184 235
     sm_wiz_last_pos.onLiveUpdate([](size_t i, float v) {
185 236
         if (i == 0) {
186 237
             steppers_move_x(v);
@@ -215,12 +266,14 @@ void states_init(void) {
215 266
         }
216 267
     });
217 268
 
269
+    // TODO
218 270
     sm_mod_preset.setTitle("Modify Preset");
219 271
     sm_mod_preset.setPrefix("Preset ");
220 272
     sm_mod_preset.dataCount([]() {
221 273
         return (int)data_preset_count();
222 274
     });
223 275
 
276
+    // TODO
224 277
     sm_del_preset.setTitle("Delete Preset");
225 278
     sm_del_preset.setPrefix("Preset ");
226 279
     sm_del_preset.dataCount([]() {
@@ -290,6 +343,65 @@ void states_init(void) {
290 343
         steppers_set_accel_e(v);
291 344
     });
292 345
 
346
+    sm_error.setChild(&sm_ask_homing);
347
+    sm_error.setTitle("Axis Error");
348
+    sm_error.setHeading("Axis Error");
349
+    sm_error.setText("Endstop has been hit!");
350
+
351
+#ifdef ENABLE_MOVEMENT_TEST_STATE
352
+    sm_movement_test.setTitle("Movement Test");
353
+
354
+    sm_move_x_test.setTitle("X Axis");
355
+    sm_move_x_test.setHeading("X Move Test");
356
+    sm_move_x_test.whenIn([](StateMachineInput smi) {
357
+        static bool s = false;
358
+        if (smi.motors_done) {
359
+            s = !s;
360
+            steppers_move_x(s ? (X_AXIS_MAX - 10.0) : (X_AXIS_MIN + 10.0));
361
+            if (smi.click) {
362
+                states_go_to(&sm_movement_test);
363
+            }
364
+        }
365
+    });
366
+
367
+    sm_move_y_test.setTitle("Y Axis");
368
+    sm_move_y_test.setHeading("Y Move Test");
369
+    sm_move_y_test.whenIn([](StateMachineInput smi) {
370
+        static bool s = false;
371
+        if (smi.motors_done) {
372
+            s = !s;
373
+            steppers_move_y(s ? (Y_AXIS_MAX - 10.0) : (Y_AXIS_MIN + 10.0));
374
+            if (smi.click) {
375
+                states_go_to(&sm_movement_test);
376
+            }
377
+        }
378
+    });
379
+#endif // ENABLE_MOVEMENT_TEST_STATE
380
+
381
+#ifdef ENABLE_INPUT_TEST_STATE
382
+    sm_input_test.setTitle("Input Test");
383
+    sm_input_test.setHeading("Input Test");
384
+
385
+    sm_input_test.whenIn([](StateMachineInput smi) {
386
+        String s = "Endstops: ";
387
+        for (int i = 0; i < 4; i++) {
388
+            if (steppers_home_switch(i)) {
389
+                s += '1';
390
+            } else {
391
+                s += '0';
392
+            }
393
+            if (i < 3) {
394
+                s += ' ';
395
+            }
396
+        }
397
+        if (s != strbuf) {
398
+            strbuf = s;
399
+            sm_input_test.setText(strbuf.c_str());
400
+            sm_input_test.updateText();
401
+        }
402
+    });
403
+#endif // ENABLE_INPUT_TEST_STATE
404
+
293 405
     // ----------------------------------
294 406
 
295 407
     states_go_to(&sm_ask_homing);

+ 228
- 22
src/steppers.cpp ファイルの表示

@@ -3,8 +3,10 @@
3 3
 
4 4
 #include "config.h"
5 5
 #include "config_pins.h"
6
+#include "common.h"
6 7
 #include "lcd.h"
7 8
 #include "data.h"
9
+#include "states.h"
8 10
 #include "steppers.h"
9 11
 
10 12
 static AccelStepper stepper_x(AccelStepper::DRIVER, X_STEP_PIN, X_DIR_PIN, 0, 0, false);
@@ -30,8 +32,8 @@ enum stepper_states {
30 32
     step_homed
31 33
 };
32 34
 
33
-static stepper_states state = step_disabled;
34
-static unsigned long steppers_home_move_start_time = 0;
35
+static volatile stepper_states state = step_disabled;
36
+static volatile unsigned long steppers_home_move_start_time = 0;
35 37
 
36 38
 void steppers_init(void) {
37 39
     pinMode(X_ENDSTOP_PIN, INPUT_PULLUP);
@@ -53,24 +55,45 @@ void steppers_init(void) {
53 55
     pinMode(E0_DIR_PIN, OUTPUT);
54 56
 
55 57
     stepper_x.setEnablePin(X_ENABLE_PIN);
56
-    stepper_x.setMaxSpeed(XY_MAX_SPEED * XY_STEPS_PER_MM);
58
+    stepper_x.setPinsInverted(false, false, true);
57 59
     steppers_set_speed_x(data_options()->speed_x);
58 60
     steppers_set_accel_x(data_options()->accel_x);
59 61
 
60 62
     stepper_y.setEnablePin(Y_ENABLE_PIN);
63
+    stepper_y.setPinsInverted(false, false, true);
61 64
     steppers_set_speed_y(data_options()->speed_y);
62 65
     steppers_set_accel_y(data_options()->accel_y);
63 66
 
64 67
     stepper_z.setEnablePin(Z_ENABLE_PIN);
68
+    stepper_z.setPinsInverted(false, false, true);
65 69
     steppers_set_speed_z(data_options()->speed_z);
66 70
     steppers_set_accel_z(data_options()->accel_z);
67 71
 
68 72
     stepper_e.setEnablePin(E0_ENABLE_PIN);
73
+    stepper_e.setPinsInverted(false, false, true);
69 74
     steppers_set_speed_e(data_options()->speed_e);
70 75
     steppers_set_accel_e(data_options()->accel_e);
71 76
 }
72 77
 
73 78
 static void steppers_initiate_home(int axis, int phase) {
79
+    Serial.print(F("steppers_initiate_home("));
80
+    if (axis == 0) {
81
+        Serial.print('X');
82
+    } else if (axis == 1) {
83
+        Serial.print('Y');
84
+    } else if (axis == 2) {
85
+        Serial.print('Z');
86
+    } else if (axis == 3) {
87
+        Serial.print('E');
88
+    } else {
89
+        Serial.print(axis);
90
+    }
91
+    Serial.print(F(", "));
92
+    Serial.print(phase);
93
+    Serial.println(F(")"));
94
+
95
+    CLEAR_STORE_INTERRUPTS();
96
+
74 97
     steppers_home_move_start_time = millis();
75 98
 
76 99
     if (axis == 0) {
@@ -124,21 +147,52 @@ static void steppers_initiate_home(int axis, int phase) {
124 147
     } else {
125 148
         Serial.println(F("home_init error: invalid axis"));
126 149
     }
150
+
151
+    RESTORE_INTERRUPTS();
127 152
 }
128 153
 
129
-static bool steppers_home_switch(int axis) {
154
+bool steppers_home_switch(int axis) {
155
+    bool r = true;
156
+    CLEAR_STORE_INTERRUPTS();
157
+
130 158
     if (axis == 0) {
131
-        return digitalRead(X_ENDSTOP_PIN) == LOW;
159
+        r = digitalRead(X_ENDSTOP_PIN) == LOW;
132 160
     } else if (axis == 1) {
133
-        return digitalRead(Y_ENDSTOP_PIN) == LOW;
161
+        r = digitalRead(Y_ENDSTOP_PIN) == LOW;
134 162
     } else if (axis == 2) {
135
-        return digitalRead(Z_ENDSTOP_PIN) == LOW;
163
+        r = digitalRead(Z_ENDSTOP_PIN) == LOW;
136 164
     } else if (axis == 3) {
137
-        return digitalRead(E_ENDSTOP_PIN) == LOW;
165
+        r = digitalRead(E_ENDSTOP_PIN) == LOW;
138 166
     } else {
139 167
         Serial.println(F("home_switch error: invalid axis"));
140 168
     }
141
-    return true;
169
+
170
+    RESTORE_INTERRUPTS();
171
+    return r;
172
+}
173
+
174
+float steppers_current_pos(int axis) {
175
+    float r = 0.0;
176
+    CLEAR_STORE_INTERRUPTS();
177
+
178
+    if (axis == 0) {
179
+        float v = stepper_x.currentPosition();
180
+        r = v / XY_STEPS_PER_MM / X_AXIS_MOVEMENT_DIR;
181
+    } else if (axis == 1) {
182
+        float v = stepper_y.currentPosition();
183
+        r = v / XY_STEPS_PER_MM / Y_AXIS_MOVEMENT_DIR;
184
+    } else if (axis == 2) {
185
+        float v = stepper_z.currentPosition();
186
+        r = v / Z_STEPS_PER_MM / Z_AXIS_MOVEMENT_DIR;
187
+    } else if (axis == 3) {
188
+        float v = stepper_e.currentPosition();
189
+        r = E_PERCENT_TO_MM(v / E_STEPS_PER_PERCENT / E_AXIS_MOVEMENT_DIR);
190
+    } else {
191
+        Serial.println(F("steppers_pos error: invalid axis"));
192
+    }
193
+
194
+    RESTORE_INTERRUPTS();
195
+    return r;
142 196
 }
143 197
 
144 198
 bool steppers_run(void) {
@@ -158,6 +212,13 @@ bool steppers_run(void) {
158 212
     } else if (state == step_homing_x_slow) {
159 213
         if (steppers_home_switch(0)) {
160 214
             stepper_x.setSpeed(0);
215
+
216
+#if (X_MIN_PIN == -1)
217
+            stepper_x.setCurrentPosition(X_AXIS_MAX * XY_STEPS_PER_MM * X_AXIS_MOVEMENT_DIR);
218
+#else
219
+            stepper_x.setCurrentPosition(X_AXIS_MIN * XY_STEPS_PER_MM * X_AXIS_MOVEMENT_DIR);
220
+#endif
221
+
161 222
             steppers_initiate_home(1, 0);
162 223
         } else {
163 224
             stepper_x.runSpeed();
@@ -178,7 +239,17 @@ bool steppers_run(void) {
178 239
     } else if (state == step_homing_y_slow) {
179 240
         if (steppers_home_switch(1)) {
180 241
             stepper_y.setSpeed(0);
181
-            steppers_initiate_home(3, 0);
242
+
243
+#if (Y_MIN_PIN == -1)
244
+            stepper_y.setCurrentPosition(Y_AXIS_MAX * XY_STEPS_PER_MM * Y_AXIS_MOVEMENT_DIR);
245
+#else
246
+            stepper_y.setCurrentPosition(Y_AXIS_MIN * XY_STEPS_PER_MM * Y_AXIS_MOVEMENT_DIR);
247
+#endif
248
+
249
+            //steppers_initiate_home(3, 0);
250
+            // TODO
251
+            state = step_homed;
252
+            return false;
182 253
         } else {
183 254
             stepper_y.runSpeed();
184 255
         }
@@ -198,6 +269,13 @@ bool steppers_run(void) {
198 269
     } else if (state == step_homing_z_slow) {
199 270
         if (steppers_home_switch(2)) {
200 271
             stepper_z.setSpeed(0);
272
+
273
+#if (Z_MIN_PIN == -1)
274
+            stepper_z.setCurrentPosition(Z_AXIS_MAX * Z_STEPS_PER_MM * Z_AXIS_MOVEMENT_DIR);
275
+#else
276
+            stepper_z.setCurrentPosition(Z_AXIS_MIN * Z_STEPS_PER_MM * Z_AXIS_MOVEMENT_DIR);
277
+#endif
278
+
201 279
             steppers_initiate_home(0, 0);
202 280
         } else {
203 281
             stepper_z.runSpeed();
@@ -218,24 +296,80 @@ bool steppers_run(void) {
218 296
     } else if (state == step_homing_e_slow) {
219 297
         if (steppers_home_switch(3)) {
220 298
             stepper_e.setSpeed(0);
299
+
300
+#if (E_MIN_PIN == -1)
301
+            stepper_e.setCurrentPosition(E_MM_TO_PERCENT(E_AXIS_MAX) * E_STEPS_PER_PERCENT * E_AXIS_MOVEMENT_DIR);
302
+#else
303
+            stepper_e.setCurrentPosition(E_MM_TO_PERCENT(E_AXIS_MIN) * E_STEPS_PER_PERCENT * E_AXIS_MOVEMENT_DIR);
304
+#endif
305
+
221 306
             state = step_homed;
222 307
             return false;
223 308
         } else {
224 309
             stepper_e.runSpeed();
225 310
         }
226 311
     } else if (state != step_disabled) {
227
-        for (int i = 0; i < 4; i++) {
228
-            if (steppers_home_switch(i)) {
229
-                Serial.print(F("ERROR: endstop hit on "));
230
-                Serial.println(i);
231
-
232
-                // TODO proper error handling?
233
-                lcd_clear();
234
-                lcd_set_heading("ERROR");
235
-                lcd_set_text("Endstop hit. Aborting!");
236
-                while (1) { }
312
+        if (state == step_homed) {
313
+            for (int i = 0; i < 4; i++) {
314
+                Serial.print(i);
315
+                Serial.print(": ");
316
+                Serial.println(steppers_current_pos(i));
317
+
318
+                float compare = 0.0, epsilon = 0.0;
319
+                if (i == 0) {
320
+                    epsilon = X_AXIS_EPSILON;
321
+#if (X_MIN_PIN == -1)
322
+                    compare = X_AXIS_MAX;
323
+#else
324
+                    compare = X_AXIS_MIN;
325
+#endif
326
+                } else if (i == 1) {
327
+                    epsilon = Y_AXIS_EPSILON;
328
+#if (Y_MIN_PIN == -1)
329
+                    compare = Y_AXIS_MAX;
330
+#else
331
+                    compare = Y_AXIS_MIN;
332
+#endif
333
+                } else if (i == 2) {
334
+                    epsilon = Z_AXIS_EPSILON;
335
+#if (Z_MIN_PIN == -1)
336
+                    compare = Z_AXIS_MAX;
337
+#else
338
+                    compare = Z_AXIS_MIN;
339
+#endif
340
+                } else if (i == 3) {
341
+                    epsilon = E_AXIS_EPSILON;
342
+#if (E_MIN_PIN == -1)
343
+                    compare = E_AXIS_MAX;
344
+#else
345
+                    compare = E_AXIS_MIN;
346
+#endif
347
+                }
348
+
349
+                if (fabs(steppers_current_pos(i) - compare) > epsilon) {
350
+                    if (steppers_home_switch(i)) {
351
+                        Serial.print(F("Endstop hit at "));
352
+                        Serial.println(steppers_current_pos(i));
353
+
354
+                        steppers_kill();
355
+
356
+                        if (i == 0) {
357
+                            sm_error.setText("Enstop hit on X axis");
358
+                        } else if (i == 1) {
359
+                            sm_error.setText("Enstop hit on Y axis");
360
+                        } else if (i == 2) {
361
+                            sm_error.setText("Enstop hit on Z axis");
362
+                        } else if (i == 3) {
363
+                            sm_error.setText("Enstop hit on E axis");
364
+                        } else {
365
+                            sm_error.setText("Enstop hit on unknown axis");
366
+                        }
367
+                        states_go_to(&sm_error);
368
+                    }
369
+                }
237 370
             }
238 371
         }
372
+
239 373
         boolean x = stepper_x.run();
240 374
         boolean y = stepper_y.run();
241 375
         boolean z = stepper_z.run();
@@ -248,14 +382,48 @@ bool steppers_run(void) {
248 382
 }
249 383
 
250 384
 bool steppers_homed(void) {
251
-    return (state == step_homed);
385
+    CLEAR_STORE_INTERRUPTS();
386
+    bool r = (state == step_homed);
387
+    RESTORE_INTERRUPTS();
388
+    return r;
389
+}
390
+
391
+char steppers_homing_axis(void) {
392
+    CLEAR_STORE_INTERRUPTS();
393
+
394
+    char r = ' ';
395
+    if ((state == step_homing_x_fast) || (state == step_homing_x_back) || (state == step_homing_x_slow)) {
396
+        r = 'X';
397
+    } else if ((state == step_homing_y_fast) || (state == step_homing_y_back) || (state == step_homing_y_slow)) {
398
+        r = 'Y';
399
+    } else if ((state == step_homing_z_fast) || (state == step_homing_z_back) || (state == step_homing_z_slow)) {
400
+        r = 'Z';
401
+    } else if ((state == step_homing_e_fast) || (state == step_homing_e_back) || (state == step_homing_e_slow)) {
402
+        r = 'E';
403
+    }
404
+
405
+    RESTORE_INTERRUPTS();
406
+    return r;
252 407
 }
253 408
 
254 409
 void steppers_start_homing(void) {
255
-    steppers_initiate_home(2, 0);
410
+    CLEAR_STORE_INTERRUPTS();
411
+
412
+    stepper_x.enableOutputs();
413
+    stepper_y.enableOutputs();
414
+    stepper_z.enableOutputs();
415
+    stepper_e.enableOutputs();
416
+
417
+    //steppers_initiate_home(2, 0);
418
+    // TODO
419
+    steppers_initiate_home(0, 0);
420
+
421
+    RESTORE_INTERRUPTS();
256 422
 }
257 423
 
258 424
 static int steppers_move_axis(AccelStepper &axis, long pos) {
425
+    CLEAR_STORE_INTERRUPTS();
426
+
259 427
     if (state == step_disabled) {
260 428
         Serial.println(F("Enabling stepper drivers"));
261 429
 
@@ -271,6 +439,8 @@ static int steppers_move_axis(AccelStepper &axis, long pos) {
271 439
     }
272 440
 
273 441
     axis.moveTo(pos);
442
+
443
+    RESTORE_INTERRUPTS();
274 444
     return 0;
275 445
 }
276 446
 
@@ -357,26 +527,36 @@ int steppers_move_e(float pos) {
357 527
 }
358 528
 
359 529
 float steppers_pos_x(void) {
530
+    CLEAR_STORE_INTERRUPTS();
360 531
     float v = stepper_x.targetPosition();
532
+    RESTORE_INTERRUPTS();
361 533
     return v / XY_STEPS_PER_MM / X_AXIS_MOVEMENT_DIR;
362 534
 }
363 535
 
364 536
 float steppers_pos_y(void) {
537
+    CLEAR_STORE_INTERRUPTS();
365 538
     float v = stepper_y.targetPosition();
539
+    RESTORE_INTERRUPTS();
366 540
     return v / XY_STEPS_PER_MM / Y_AXIS_MOVEMENT_DIR;
367 541
 }
368 542
 
369 543
 float steppers_pos_z(void) {
544
+    CLEAR_STORE_INTERRUPTS();
370 545
     float v = stepper_z.targetPosition();
546
+    RESTORE_INTERRUPTS();
371 547
     return v / Z_STEPS_PER_MM / Z_AXIS_MOVEMENT_DIR;
372 548
 }
373 549
 
374 550
 float steppers_pos_e(void) {
551
+    CLEAR_STORE_INTERRUPTS();
375 552
     float v = stepper_e.targetPosition();
553
+    RESTORE_INTERRUPTS();
376 554
     return E_PERCENT_TO_MM(v / E_STEPS_PER_PERCENT / E_AXIS_MOVEMENT_DIR);
377 555
 }
378 556
 
379 557
 void steppers_kill(void) {
558
+    CLEAR_STORE_INTERRUPTS();
559
+
380 560
     stepper_x.setCurrentPosition(0);
381 561
     stepper_y.setCurrentPosition(0);
382 562
     stepper_z.setCurrentPosition(0);
@@ -388,6 +568,8 @@ void steppers_kill(void) {
388 568
     stepper_e.disableOutputs();
389 569
 
390 570
     state = step_not_homed;
571
+
572
+    RESTORE_INTERRUPTS();
391 573
 }
392 574
 
393 575
 void steppers_set_speed_x(float speed) {
@@ -397,7 +579,10 @@ void steppers_set_speed_x(float speed) {
397 579
     if (speed > XY_MAX_SPEED) {
398 580
         speed = XY_MAX_SPEED;
399 581
     }
582
+
583
+    CLEAR_STORE_INTERRUPTS();
400 584
     stepper_x.setMaxSpeed(speed * XY_STEPS_PER_MM);
585
+    RESTORE_INTERRUPTS();
401 586
 }
402 587
 
403 588
 void steppers_set_speed_y(float speed) {
@@ -407,7 +592,10 @@ void steppers_set_speed_y(float speed) {
407 592
     if (speed > XY_MAX_SPEED) {
408 593
         speed = XY_MAX_SPEED;
409 594
     }
595
+
596
+    CLEAR_STORE_INTERRUPTS();
410 597
     stepper_y.setMaxSpeed(speed * XY_STEPS_PER_MM);
598
+    RESTORE_INTERRUPTS();
411 599
 }
412 600
 
413 601
 void steppers_set_speed_z(float speed) {
@@ -417,7 +605,10 @@ void steppers_set_speed_z(float speed) {
417 605
     if (speed > Z_MAX_SPEED) {
418 606
         speed = Z_MAX_SPEED;
419 607
     }
608
+
609
+    CLEAR_STORE_INTERRUPTS();
420 610
     stepper_z.setMaxSpeed(speed * Z_STEPS_PER_MM);
611
+    RESTORE_INTERRUPTS();
421 612
 }
422 613
 
423 614
 void steppers_set_speed_e(float speed) {
@@ -427,7 +618,10 @@ void steppers_set_speed_e(float speed) {
427 618
     if (speed > E_MAX_SPEED) {
428 619
         speed = E_MAX_SPEED;
429 620
     }
621
+
622
+    CLEAR_STORE_INTERRUPTS();
430 623
     stepper_e.setMaxSpeed(speed * E_STEPS_PER_PERCENT);
624
+    RESTORE_INTERRUPTS();
431 625
 }
432 626
 
433 627
 void steppers_set_accel_x(float accel) {
@@ -437,7 +631,10 @@ void steppers_set_accel_x(float accel) {
437 631
     if (accel > XY_MAX_ACCEL) {
438 632
         accel = XY_MAX_ACCEL;
439 633
     }
634
+
635
+    CLEAR_STORE_INTERRUPTS();
440 636
     stepper_x.setAcceleration(accel * XY_STEPS_PER_MM);
637
+    RESTORE_INTERRUPTS();
441 638
 }
442 639
 
443 640
 void steppers_set_accel_y(float accel) {
@@ -447,7 +644,10 @@ void steppers_set_accel_y(float accel) {
447 644
     if (accel > XY_MAX_ACCEL) {
448 645
         accel = XY_MAX_ACCEL;
449 646
     }
647
+
648
+    CLEAR_STORE_INTERRUPTS();
450 649
     stepper_y.setAcceleration(accel * XY_STEPS_PER_MM);
650
+    RESTORE_INTERRUPTS();
451 651
 }
452 652
 
453 653
 void steppers_set_accel_z(float accel) {
@@ -457,7 +657,10 @@ void steppers_set_accel_z(float accel) {
457 657
     if (accel > Z_MAX_ACCEL) {
458 658
         accel = Z_MAX_ACCEL;
459 659
     }
660
+
661
+    CLEAR_STORE_INTERRUPTS();
460 662
     stepper_z.setAcceleration(accel * Z_STEPS_PER_MM);
663
+    RESTORE_INTERRUPTS();
461 664
 }
462 665
 
463 666
 void steppers_set_accel_e(float accel) {
@@ -467,5 +670,8 @@ void steppers_set_accel_e(float accel) {
467 670
     if (accel > E_MAX_ACCEL) {
468 671
         accel = E_MAX_ACCEL;
469 672
     }
673
+
674
+    CLEAR_STORE_INTERRUPTS();
470 675
     stepper_e.setAcceleration(accel * E_STEPS_PER_PERCENT);
676
+    RESTORE_INTERRUPTS();
471 677
 }

読み込み中…
キャンセル
保存