1
+ const int XSTP = 2 ;
2
+ const int YSTP = 3 ;
3
+ const int ZSTP = 4 ;
4
+ const int XDIR = 5 ;
5
+ const int YDIR = 6 ;
6
+ const int ZDIR = 7 ;
7
+ const int EN = 8 ;
8
+ const int XLIM = 9 ;
9
+ const int YLIM = 10 ;
10
+ const int ZLIM = 11 ;
11
+ const int ASTP = 12 ;
12
+ const int ADIR = 13 ;
13
+ const int ABORT = A0;
14
+ const int HOLD = A1;
15
+ const int RESUME = A2;
16
+ const int COOLANT = A3;
17
+
18
+ const int N_AXIS = 2 ;
19
+ const int N_SEGMENTS = 1 ;
20
+ const float STEP_SIZE = 0 .05f ; // mm
21
+
22
+ struct Segment {
23
+ uint8_t directions[N_AXIS];
24
+ uint32_t steps[N_AXIS];
25
+ float initSpeedSqr; // (step/s)^2
26
+ float topSpeedSqr;
27
+ float exitSpeedSqr;
28
+ float acceleration; // step/s^2
29
+ };
30
+
31
+ Segment segments[N_SEGMENTS];
32
+
33
+ void initMotors () {
34
+ pinMode (EN, OUTPUT);
35
+ digitalWrite (EN, HIGH);
36
+ for (uint8_t a = 0 ; a < N_AXIS; ++a) {
37
+ pinMode (XSTP + a, OUTPUT);
38
+ pinMode (XDIR + a, OUTPUT);
39
+ }
40
+ }
41
+
42
+ void enableMotors () {
43
+ for (uint8_t a = 0 ; a < N_AXIS; ++a) {
44
+ digitalWrite (XDIR + a, HIGH);
45
+ }
46
+ for (uint8_t a = 0 ; a < N_AXIS; ++a) {
47
+ digitalWrite (XSTP + a, LOW);
48
+ }
49
+ digitalWrite (EN, LOW);
50
+ }
51
+
52
+ void disableMotors () {
53
+ digitalWrite (EN, HIGH);
54
+ }
55
+
56
+ void setDirection (uint8_t axis, bool direction) {
57
+ digitalWrite (XDIR + axis, direction);
58
+ }
59
+
60
+ void sendStep (uint8_t axis) {
61
+ digitalWrite (XSTP + axis, !digitalRead (XSTP));
62
+ }
63
+
64
+ void delayFor (float stepTime) {
65
+ delayMicroseconds (unsigned (stepTime * 1000000 .0f ));
66
+ }
67
+
68
+ void sendSegment (Segment const &segment) {
69
+ uint32_t maxAxisSteps = 0 ;
70
+ uint32_t maxAxis = N_AXIS;
71
+ for (uint8_t a = 0 ; a < N_AXIS; ++a) {
72
+ setDirection (a, segment.directions [a]);
73
+ if (segment.steps [a] > maxAxisSteps) {
74
+ maxAxisSteps = segment.steps [a];
75
+ maxAxis = a;
76
+ }
77
+ }
78
+ if (maxAxisSteps == 0 ) {
79
+ return ;
80
+ }
81
+
82
+ float topStepTime = 1 .0f / sqrtf (segment.topSpeedSqr );
83
+ float invertAcceleration = 1 .0f / segment.acceleration ;
84
+ float twiceAcceleration = 2 .0f * segment.acceleration ;
85
+ int slaveAxis = 1 - maxAxis;
86
+ int slaveDelta = 2 * segment.steps [slaveAxis] - maxAxisSteps;
87
+ for (uint32_t i = 0 ; i < maxAxisSteps; ++i) {
88
+ float speed1Sqr = segment.initSpeedSqr + twiceAcceleration * i;
89
+ float speed2Sqr = segment.exitSpeedSqr + twiceAcceleration * (maxAxisSteps - 1 - i);
90
+ float speedMinSqr = fminf (speed1Sqr, speed2Sqr);
91
+ float stepTime;
92
+ if (speedMinSqr >= segment.topSpeedSqr ) {
93
+ stepTime = topStepTime;
94
+ } else {
95
+ stepTime = (sqrtf (speedMinSqr + twiceAcceleration) - sqrtf (speedMinSqr)) * invertAcceleration;
96
+ }
97
+ sendStep (maxAxis);
98
+ if (slaveDelta > 0 ) {
99
+ sendStep (slaveAxis);
100
+ slaveDelta -= 2 * maxAxisSteps;
101
+ }
102
+ slaveDelta += 2 * segment.steps [slaveAxis];
103
+ delayFor (stepTime);
104
+ }
105
+ }
106
+
107
+ void setup () {
108
+ Serial.begin (115200 );
109
+
110
+ segments[0 ].directions [0 ] = 1 ;
111
+ segments[0 ].steps [0 ] = 1000 ;
112
+ segments[0 ].directions [1 ] = 0 ;
113
+ segments[0 ].steps [1 ] = 300 ;
114
+ segments[0 ].acceleration = 4000 ;
115
+ segments[0 ].initSpeedSqr = squaref (10 );
116
+ segments[0 ].topSpeedSqr = squaref (1000 );
117
+ segments[0 ].exitSpeedSqr = squaref (10 );
118
+
119
+ initMotors ();
120
+ enableMotors ();
121
+ }
122
+
123
+ void loop () {
124
+ sendSegment (segments[0 ]);
125
+ delay (100 );
126
+ }
127
+ // s=v0t+0.5at^2
128
+ // 0.5a t^2 + v0 t - s = 0
129
+ // delta = v0^2 + 2as
130
+ // t = (-v0 +- sqrt delta) / a
131
+ // t = (sqrt(v0^2 + 2as) - v0) / a
132
+ // v = sqrt(v0^2 + 2as)
0 commit comments