iFBalance-코딩으로 뽀샤버리기

4강. DC 모터 제어하기

Posted by INDIFROG on 2021-03-04
Words 587 and Reading Time 3 Minutes
Viewed Times

4강. DC 모터 제어하기

아래 그림은 iFBalance 로봇에서 사용된 iFZero 보드의 GPIO에 할당된 Pin Map입니다. iFBalance는 iFLine 보다 IR 센서부가 좀 더 복잡하기 때문에 제어 및 ADC 핀이 추가 할당이 되어 있습니다.

그러나 DC 모터를 제어하는 부분은 iFLine보다 줄어서 다행히 여분의 GPIO가 2개정도 남은 상태입니다.

VSCODE_LIB

DC 모터를 제어하기 위해 할당된 GPIO는 다음과 같다.

  Motor Control                     GPIO

  LEFT_WHEEL_FORWARD                IO7
  LEFT_WHEEL_BACKWARD               IO8
  RIGHT_WHEEL_FORWARD               IO27
  RIGHT_WHEEL_BACKWARD              IO26

DC 모터에 대한 PWM 제어등에 관한 내용은 기존 잘 설명이 되어 있는 iFLine 강좌를 먼저 참조하시기 바랍니다.

2020-06-28-iFLine-개발강좌_06 ➾

VSCODE_LIB

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
/******************************************************************************
iFMotors.h - iFBalance Arduino Library
hkkim@koreaits.com ( KITS Lab )
original creation date: April 3, 2020

Development environment specifics:
Arduino IDE 1.8.x
iFBalance
******************************************************************************/

#ifndef iFMotors_v1_h
#define iFMotors_v1_h
#define iFMOTORS_LIBRARY_VERSION 1.1.1

#include <Arduino.h>

#define MC_LEFT_CH (0)
#define MC_RIGHT_CH (15)
#define FREQUENCY (5000)

#define FORWARD 1
#define BACKWARD 0

#define MIN_ABS_SPEED (1)

#define LEFT_F 7
#define LEFT_R 8
#define RIGHT_F 27
#define RIGHT_R 26


#define LEFT_F_CH (0)
#define LEFT_R_CH (1)
#define RIGHT_F_CH (2)
#define RIGHT_R_CH (3)

/* PWM resolution */
#define PWM_RES (10)
#define PWM_BASE_FREQ (5 * 1000) // 5 kHz

class iFMotors{
private:
const int _nPWMResBit = 10;
int _nMaxSpeed;
int _nType = 1;

public:
iFMotors(){}

void init();

int move(int lspeed, int rspeed);

void motorStop();
int getMaxSpeed(){ return _nMaxSpeed; }
};

#endif
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

/******************************************************************************
iFMotors.cpp - iFBalance Arduino Library
hkkim@koreaits.com ( KITS Lab )
original creation date: April 3, 2020

Development environment specifics:
Arduino IDE 1.8.x
iFBalance
******************************************************************************/

#include "iFMotors.h"

void iFMotors::init(){

ledcSetup(LEFT_F_CH, FREQUENCY, _nPWMResBit);
ledcSetup(LEFT_R_CH, FREQUENCY, _nPWMResBit);
ledcSetup(RIGHT_F_CH, FREQUENCY, _nPWMResBit);
ledcSetup(RIGHT_R_CH, FREQUENCY, _nPWMResBit);

ledcAttachPin(LEFT_F, LEFT_F_CH);
ledcAttachPin(LEFT_R, LEFT_R_CH);
ledcAttachPin(RIGHT_F, RIGHT_F_CH);
ledcAttachPin(RIGHT_R, RIGHT_R_CH);

ledcWrite(LEFT_F_CH, 0 );
ledcWrite(LEFT_R_CH, 0 );
ledcWrite(RIGHT_F_CH, 0 );
ledcWrite(RIGHT_R_CH, 0 );

_nMaxSpeed = (int) pow(2, _nPWMResBit) ;

motorStop();
}

void iFMotors::motorStop()
{
ledcWrite(LEFT_F_CH, 0 );
ledcWrite(LEFT_R_CH, 0 );
ledcWrite(RIGHT_F_CH, 0 );
ledcWrite(RIGHT_R_CH, 0 );
}

int iFMotors::move(int lspeed, int rspeed)
{

#if 1
int ldirection = 1, rdirection = 1;
if (lspeed < 0 ){
ldirection = -1;
}
else{
ldirection = 1;
}
if (rspeed < 0 ){
rdirection = -1;
}
else{
rdirection = 1;
}

lspeed = map( abs(lspeed) , 0, _nMaxSpeed, MIN_ABS_SPEED*_nPWMResBit, _nMaxSpeed);
rspeed = map( abs(rspeed) , 0, _nMaxSpeed, MIN_ABS_SPEED*_nPWMResBit, _nMaxSpeed);

// lspeed = map( abs(lspeed) , 0, _nMaxSpeed, 400, _nMaxSpeed);
// rspeed = map( abs(rspeed) , 0, _nMaxSpeed, 400, _nMaxSpeed);
if( lspeed > _nMaxSpeed ) lspeed =_nMaxSpeed;
if( rspeed > _nMaxSpeed ) rspeed =_nMaxSpeed;

// printf("lo : %d, ro = %d, t = %d\n", lspeed, rspeed, ldirection);

if( ldirection == 1 ){
ledcWrite(LEFT_F_CH, abs(lspeed)-1 );
ledcWrite(LEFT_R_CH, 0);

}
else{
ledcWrite(LEFT_F_CH, 0);
ledcWrite(LEFT_R_CH, abs(lspeed)-1 );
}

if( rdirection == 1 ){
ledcWrite(RIGHT_F_CH, 0 );
ledcWrite(RIGHT_R_CH, abs(rspeed)-1 );

}else{
ledcWrite(RIGHT_F_CH, abs(rspeed)-1);
ledcWrite(RIGHT_R_CH, 0 );

}
#endif

return 0;
}
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
/******************************************************************************
main.cpp - iFLine, iFBalance Arduino Library
hkkim@koreaits.com ( KITS Lab )
original creation date: April 3, 2020

Development environment specifics:
Arduino IDE 1.8.x
iFBalance
******************************************************************************/

#include <Arduino.h>
#include "iFLED.h"
#include "iFMotors.h"

iFLED ifLed;
iFMotors ifMotors;

void setup()
{
Serial.begin(115200);

///////////////////////////////////////////////////////
// Color LED
ifLed.init();
ifLed.setMode( BLINK );


///////////////////////////////////////////////////////
// Motor
ifMotors.init();
ifMotors.move( 450, 450);
}

void loop() {

}

iFBalance의 iFMotors 클래스의 사용법은 극단적으로 편리합니다. 멈추기 위해서는 move 멤버함수에 0을 입력하면 되고 전방향으로 최대 출력을 위해서는 1023 ( 1024 - 1 ) 입력하면 됩니다.
반대로 역방향으로 움직이기 위해서는 - 값을 입력하면 됩니다.

또한 모터마다 기동 토크가 다를 수 있지만 최소 움직이기 시작하는 PWM 값은 450 정도임을 참고하시기 바랍니다.

이상으로 이번 강좌에서는 모터를 제어하기 위해 작성된 iFMotors 클래스에 대해 살펴보았습니다.