2019. 11. 22. 15:30

저번에 "한 번에 2개 이상의 스테핑 모터를 제어하기"를 했었는데.......

'Stepper'라이브러리가 업데이트 많이 됐군요. ㅎㅎㅎ


버전에 맞춰 업데이트해보았습니다.




이전 글에서 'Stepper.h'는 '.step()'이 동작하는 동안 다른 동작을 할 수 없다고 이야기했습니다.

(참고 : [Arduino] 'Stepper.h'는 두개의 모터를 제어할 수 없다. )

그래서 'Stepper.h'를 수정한 라이브러를 작성하고 사용하는 방법에 대한 포스팅입니다.




기존 'Stepper'를 수정하는 방법은 이전 글에서 다뤘으므로 이 포스팅은 수정된 코드만 나열합니다.



1. Stepper.h -> StepperMulti5.h

헤더는 거의 그대로입니다.


참고 : github - StepperMulti5.h


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
/*
  StepperMulti5.h
  ( http://blog.danggun.net/2092 )
  이 라이브러리는 아두이노의 'Stepper.h'를 개조한 라이브러리입니다.
  (Stepper.h : http://arduino.cc/en/reference/stepper )
  모든 내용은 'Stepper.h'와 거의 동일합니다.
  (1.1.0버전 기준)
*/
 
/*
 * Stepper.h - Stepper library for Wiring/Arduino - Version 1.1.0
 *
 * Original library        (0.1)   by Tom Igoe.
 * Two-wire modifications  (0.2)   by Sebastian Gassner
 * Combination version     (0.3)   by Tom Igoe and David Mellis
 * Bug fix for four-wire   (0.4)   by Tom Igoe, bug fix from Noah Shibley
 * High-speed stepping mod         by Eugene Kozlenko
 * Timer rollover fix              by Eugene Kozlenko
 * Five phase five wire    (1.1.0) by Ryan Orendorff
 *
 *
 * http://www.arduino.cc/en/Tutorial/Stepper
 */
 
// ensure this library description is only included once
#ifndef StepperMulti5_h
#define StepperMulti5_h
 
// library interface description
class StepperMulti5 {
  public:
    // constructors:
    StepperMulti5(int number_of_steps, int motor_pin_1, int motor_pin_2);
    StepperMulti5(int number_of_steps, int motor_pin_1, int motor_pin_2,
                                        int motor_pin_3, int motor_pin_4);
    StepperMulti5(int number_of_steps, int motor_pin_1, int motor_pin_2,
                                        int motor_pin_3, int motor_pin_4,
                                        int motor_pin_5);
 
    // speed setter method:
    void setSpeed(long whatSpeed);
 
    // mover method:
    void setStep(int number_of_steps);
    //'loop()'안에서 이 메소드를 호출해야 한다.
    void moveStep();
 
    int version(void);
 
  private:
    void stepMotor(int this_step);
 
    int direction;            // Direction of rotation
    unsigned long step_delay; // delay between steps, in ms, based on speed
    int number_of_steps;      // total number of steps this motor can take
    int pin_count;            // how many pins are in use.
    int step_number;          // which step the motor is on
 
    // motor pin numbers:
    int motor_pin_1;
    int motor_pin_2;
    int motor_pin_3;
    int motor_pin_4;
    int motor_pin_5;          // Only 5 phase motor
 
    unsigned long last_step_time; // time stamp in us of when the last step was taken
 
    //스템 저장
    int steps_left;
};
 
#endif
 
 
cs



2. Stepper.cpp -> StepperMulti5.cpp

약간 바뀐 것이 있는데.....크진 않습니다.


step_number

this->step_number

로 바꿔줍니다.


참고 : github - StepperMulti5.cpp


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
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
/*
  StepperMulti5.h
  ( http://blog.danggun.net/2092 )
  이 라이브러리는 아두이노의 'Stepper.h'를 개조한 라이브러리입니다.
  (Stepper.h : http://arduino.cc/en/reference/stepper )
  모든 내용은 'Stepper.h'와 거의 동일합니다.
  (1.1.0버전 기준)
*/
 
/*
 * Stepper.cpp - Stepper library for Wiring/Arduino - Version 1.1.0
 *
 * Original library        (0.1)   by Tom Igoe.
 * Two-wire modifications  (0.2)   by Sebastian Gassner
 * Combination version     (0.3)   by Tom Igoe and David Mellis
 * Bug fix for four-wire   (0.4)   by Tom Igoe, bug fix from Noah Shibley
 * High-speed stepping mod         by Eugene Kozlenko
 * Timer rollover fix              by Eugene Kozlenko
 * Five phase five wire    (1.1.0) by Ryan Orendorff
 *
 * http://www.arduino.cc/en/Tutorial/Stepper
 */
 
#include "Arduino.h"
//헤더 연결 변경
#include "StepperMulti5.h"
 
/*
 * two-wire constructor.
 * Sets which wires should control the motor.
 */
StepperMulti5::StepperMulti5(int number_of_steps, int motor_pin_1, int motor_pin_2)
{
  //스탭초기화
  this->steps_left = 0;
 
  this->step_number = 0;    // which step the motor is on
  this->direction = 0;      // motor direction
  this->last_step_time = 0// time stamp in us of the last step taken
  this->number_of_steps = number_of_steps; // total number of steps for this motor
 
  // Arduino pins for the motor control connection:
  this->motor_pin_1 = motor_pin_1;
  this->motor_pin_2 = motor_pin_2;
 
  // setup the pins on the microcontroller:
  pinMode(this->motor_pin_1, OUTPUT);
  pinMode(this->motor_pin_2, OUTPUT);
 
  // When there are only 2 pins, set the others to 0:
  this->motor_pin_3 = 0;
  this->motor_pin_4 = 0;
  this->motor_pin_5 = 0;
 
  // pin_count is used by the stepMotor() method:
  this->pin_count = 2;
}
 
 
/*
 *   constructor for four-pin version
 *   Sets which wires should control the motor.
 */
StepperMulti5::StepperMulti5(int number_of_steps, int motor_pin_1, int motor_pin_2,
                                      int motor_pin_3, int motor_pin_4)
{
  //스탭초기화
  this->steps_left = 0;
 
  this->step_number = 0;    // which step the motor is on
  this->direction = 0;      // motor direction
  this->last_step_time = 0// time stamp in us of the last step taken
  this->number_of_steps = number_of_steps; // total number of steps for this motor
 
  // Arduino pins for the motor control connection:
  this->motor_pin_1 = motor_pin_1;
  this->motor_pin_2 = motor_pin_2;
  this->motor_pin_3 = motor_pin_3;
  this->motor_pin_4 = motor_pin_4;
 
  // setup the pins on the microcontroller:
  pinMode(this->motor_pin_1, OUTPUT);
  pinMode(this->motor_pin_2, OUTPUT);
  pinMode(this->motor_pin_3, OUTPUT);
  pinMode(this->motor_pin_4, OUTPUT);
 
  // When there are 4 pins, set the others to 0:
  this->motor_pin_5 = 0;
 
  // pin_count is used by the stepMotor() method:
  this->pin_count = 4;
}
 
/*
 *   constructor for five phase motor with five wires
 *   Sets which wires should control the motor.
 */
StepperMulti5::StepperMulti5(int number_of_steps, int motor_pin_1, int motor_pin_2,
                                      int motor_pin_3, int motor_pin_4,
                                      int motor_pin_5)
{
 
  //스탭초기화
  this->steps_left = 0;
 
  this->step_number = 0;    // which step the motor is on
  this->direction = 0;      // motor direction
  this->last_step_time = 0// time stamp in us of the last step taken
  this->number_of_steps = number_of_steps; // total number of steps for this motor
 
  // Arduino pins for the motor control connection:
  this->motor_pin_1 = motor_pin_1;
  this->motor_pin_2 = motor_pin_2;
  this->motor_pin_3 = motor_pin_3;
  this->motor_pin_4 = motor_pin_4;
  this->motor_pin_5 = motor_pin_5;
 
  // setup the pins on the microcontroller:
  pinMode(this->motor_pin_1, OUTPUT);
  pinMode(this->motor_pin_2, OUTPUT);
  pinMode(this->motor_pin_3, OUTPUT);
  pinMode(this->motor_pin_4, OUTPUT);
  pinMode(this->motor_pin_5, OUTPUT);
 
  // pin_count is used by the stepMotor() method:
  this->pin_count = 5;
}
 
/*
 * Sets the speed in revs per minute
 */
void StepperMulti5::setSpeed(long whatSpeed)
{
  this->step_delay = 60L * 1000L * 1000L / this->number_of_steps / whatSpeed;
}
 
/*
 * Moves the motor steps_to_move steps.  If the number is negative,
 * the motor moves in the reverse direction.
 */
void StepperMulti5::setStep(int steps_to_move)
{
  //전역 번수에 스탭을 저장한다.
  this->steps_left = abs(steps_to_move);  // how many steps to take
 
  // determine direction based on whether steps_to_mode is + or -:
  if (steps_to_move > 0) { this->direction = 1; }
  if (steps_to_move < 0) { this->direction = 0; }
 
 
  //스탭을 진행 한다.
  moveStep();
}
 
/*
 * loop안에서 호출하여 스탭모터의 동작을 제어한다.
*/
void StepperMulti5::moveStep()
{
    // decrement the number of steps, moving one step each time:
    // while -> if
    // 'while'의 역할을 'loop'가 대신 해주기 때문에 여기서는 'while'가 필요없다.
    //while (steps_left > 0)
    if(this->steps_left > 0)
    {
        unsigned long now = micros();
        // move only if the appropriate delay has passed:
        if (now - this->last_step_time >= this->step_delay)
        {
            // get the timeStamp of when you stepped:
            this->last_step_time = now;
            // increment or decrement the step number,
            // depending on direction:
            if (this->direction == 1)
            {
                this->step_number++;
                if (this->step_number == this->number_of_steps) {
                    this->step_number = 0;
                }
            }
            else
            {
                if (this->step_number == 0) {
                    this->step_number = this->number_of_steps;
                }
                this->step_number--;
            }
            
            //스탭 남은 개수를 전역변수에 저장한다.
            this->steps_left--;// decrement the steps left:
            // step the motor to step number 0, 1, ..., {3 or 10}
            if (this->pin_count == 5)
                stepMotor(this->step_number % 10);
            else
                stepMotor(this->step_number % 4);
        }
    }
}
 
 
/*
 * Moves the motor forward or backwards.
 */
void StepperMulti5::stepMotor(int thisStep)
{
  if (this->pin_count == 2) {
    switch (thisStep) {
      case 0:  // 01
        digitalWrite(motor_pin_1, LOW);
        digitalWrite(motor_pin_2, HIGH);
      break;
      case 1:  // 11
        digitalWrite(motor_pin_1, HIGH);
        digitalWrite(motor_pin_2, HIGH);
      break;
      case 2:  // 10
        digitalWrite(motor_pin_1, HIGH);
        digitalWrite(motor_pin_2, LOW);
      break;
      case 3:  // 00
        digitalWrite(motor_pin_1, LOW);
        digitalWrite(motor_pin_2, LOW);
      break;
    }
  }
  if (this->pin_count == 4) {
    switch (thisStep) {
      case 0:  // 1010
        digitalWrite(motor_pin_1, HIGH);
        digitalWrite(motor_pin_2, LOW);
        digitalWrite(motor_pin_3, HIGH);
        digitalWrite(motor_pin_4, LOW);
      break;
      case 1:  // 0110
        digitalWrite(motor_pin_1, LOW);
        digitalWrite(motor_pin_2, HIGH);
        digitalWrite(motor_pin_3, HIGH);
        digitalWrite(motor_pin_4, LOW);
      break;
      case 2:  //0101
        digitalWrite(motor_pin_1, LOW);
        digitalWrite(motor_pin_2, HIGH);
        digitalWrite(motor_pin_3, LOW);
        digitalWrite(motor_pin_4, HIGH);
      break;
      case 3:  //1001
        digitalWrite(motor_pin_1, HIGH);
        digitalWrite(motor_pin_2, LOW);
        digitalWrite(motor_pin_3, LOW);
        digitalWrite(motor_pin_4, HIGH);
      break;
    }
  }
 
  if (this->pin_count == 5) {
    switch (thisStep) {
      case 0:  // 01101
        digitalWrite(motor_pin_1, LOW);
        digitalWrite(motor_pin_2, HIGH);
        digitalWrite(motor_pin_3, HIGH);
        digitalWrite(motor_pin_4, LOW);
        digitalWrite(motor_pin_5, HIGH);
        break;
      case 1:  // 01001
        digitalWrite(motor_pin_1, LOW);
        digitalWrite(motor_pin_2, HIGH);
        digitalWrite(motor_pin_3, LOW);
        digitalWrite(motor_pin_4, LOW);
        digitalWrite(motor_pin_5, HIGH);
        break;
      case 2:  // 01011
        digitalWrite(motor_pin_1, LOW);
        digitalWrite(motor_pin_2, HIGH);
        digitalWrite(motor_pin_3, LOW);
        digitalWrite(motor_pin_4, HIGH);
        digitalWrite(motor_pin_5, HIGH);
        break;
      case 3:  // 01010
        digitalWrite(motor_pin_1, LOW);
        digitalWrite(motor_pin_2, HIGH);
        digitalWrite(motor_pin_3, LOW);
        digitalWrite(motor_pin_4, HIGH);
        digitalWrite(motor_pin_5, LOW);
        break;
      case 4:  // 11010
        digitalWrite(motor_pin_1, HIGH);
        digitalWrite(motor_pin_2, HIGH);
        digitalWrite(motor_pin_3, LOW);
        digitalWrite(motor_pin_4, HIGH);
        digitalWrite(motor_pin_5, LOW);
        break;
      case 5:  // 10010
        digitalWrite(motor_pin_1, HIGH);
        digitalWrite(motor_pin_2, LOW);
        digitalWrite(motor_pin_3, LOW);
        digitalWrite(motor_pin_4, HIGH);
        digitalWrite(motor_pin_5, LOW);
        break;
      case 6:  // 10110
        digitalWrite(motor_pin_1, HIGH);
        digitalWrite(motor_pin_2, LOW);
        digitalWrite(motor_pin_3, HIGH);
        digitalWrite(motor_pin_4, HIGH);
        digitalWrite(motor_pin_5, LOW);
        break;
      case 7:  // 10100
        digitalWrite(motor_pin_1, HIGH);
        digitalWrite(motor_pin_2, LOW);
        digitalWrite(motor_pin_3, HIGH);
        digitalWrite(motor_pin_4, LOW);
        digitalWrite(motor_pin_5, LOW);
        break;
      case 8:  // 10101
        digitalWrite(motor_pin_1, HIGH);
        digitalWrite(motor_pin_2, LOW);
        digitalWrite(motor_pin_3, HIGH);
        digitalWrite(motor_pin_4, LOW);
        digitalWrite(motor_pin_5, HIGH);
        break;
      case 9:  // 00101
        digitalWrite(motor_pin_1, LOW);
        digitalWrite(motor_pin_2, LOW);
        digitalWrite(motor_pin_3, HIGH);
        digitalWrite(motor_pin_4, LOW);
        digitalWrite(motor_pin_5, HIGH);
        break;
    }
  }
}
 
/*
  version() returns the version of the library:
*/
int StepperMulti5::version(void)
{
  return 5;
}
 
cs



3. 테스트
이제 테스트 코드를 만들어 봅시다.


참고 : github - StepperMulti5_Examples.ino


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
#include <StepperMulti5.h>
 
StepperMulti5 stepper(2001211109);
StepperMulti5 stepper2(2007654);
 
void setup() 
{
  Serial.begin(9600);
  stepper.setSpeed(30);
  stepper2.setSpeed(60);
}
 
void loop() 
{
  if (Serial.available())
  {
    int steps = Serial.parseInt();
 
    if(steps != 0)
    {
      stepper.setStep(steps);
      stepper2.setStep(steps);
      //stepper.setStep(200);
      //stepper2.setStep(200);
  
      Serial.print("steps : ");
      Serial.println(steps); 
    }
    
  }
  
  stepper.moveStep();
  stepper2.moveStep();
 
}
cs



이제 테스트를 해봅시다.




마무리
완성된 샘플 : Github - Arduino_StepperMulti/StepperMulti5/

이제는 라이브러리에 출력 버전이 있네요.

출력 버전에 맞춰 이름을 바꿀 예정입니다.


댓글 작성

이름
패스워드
홈페이지
비밀글